security test peripheral working

This commit is contained in:
matthias.ringwald@gmail.com 2014-04-17 13:17:47 +00:00
parent 116c0afde4
commit c480cc0ffd
2 changed files with 229 additions and 62 deletions

View File

@ -14,11 +14,35 @@
static btstack_packet_handler_t le_data_handler;
static void (*event_packet_handler) (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) = NULL;
static const uint16_t max_mtu = 23;
static uint8_t l2cap_stack_buffer[max_mtu];
static uint8_t packet_buffer[256];
static uint16_t packet_buffer_len = 0;
static uint8_t aes128_cyphertext[16];
uint8_t * mock_packet_buffer(void){
return packet_buffer;
}
void mock_clear_packet_buffer(void){
packet_buffer_len = 0;
}
static void dump_packet(int packet_type, uint8_t * buffer, uint16_t size){
#if 0
static int packet_counter = 1;
char var_name[80];
sprintf(var_name, "test_%s_packet_%02u", packet_type == HCI_COMMAND_DATA_PACKET ? "command" : "acl", packet_counter);
printf("uint8_t %s[] = { ", var_name);
for (int i = 0; i < size ; i++){
if ((i % 16) == 0) printf("\n ");
printf ("0x%02x, ", buffer[i]);
}
printf("};\n");
packet_counter++;
#endif
}
void aes128_calc_cyphertext(uint8_t key[16], uint8_t plaintext[16], uint8_t cyphertext[16]){
uint32_t rk[RKLENGTH(KEYBITS)];
int nrounds = rijndaelSetupEncrypt(rk, &key[0], KEYBITS);
@ -94,48 +118,37 @@ void hci_le_advertisement_address(uint8_t * addr_type, bd_addr_t * addr){
}
int l2cap_can_send_connectionless_packet_now(void){
return 1;
return packet_buffer_len == 0;
}
int hci_send_cmd(const hci_cmd_t *cmd, ...){
uint8_t cmd_buffer[256];
va_list argptr;
va_start(argptr, cmd);
uint16_t len = hci_create_cmd_internal(cmd_buffer, cmd, argptr);
uint16_t len = hci_create_cmd_internal(packet_buffer, cmd, argptr);
va_end(argptr);
hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, cmd_buffer, len);
hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, packet_buffer, len);
dump_packet(HCI_COMMAND_DATA_PACKET, packet_buffer, len);
packet_buffer_len = len;
// track le encrypt and le rand
if (cmd->opcode == hci_le_encrypt.opcode){
uint8_t * key_flipped = &cmd_buffer[3];
uint8_t * plaintext_flipped = &cmd_buffer[19];
uint8_t * key_flipped = &packet_buffer[3];
uint8_t key[16];
uint8_t plaintext[16];
swap128(key_flipped, key);
// printf("le_encrypt key ");
// hexdump(key, 16);
uint8_t * plaintext_flipped = &packet_buffer[19];
uint8_t plaintext[16];
swap128(plaintext_flipped, plaintext);
printf("le_encrypt key ");
hexdump(key, 16);
printf("le_encrypt txt ");
hexdump(plaintext, 16);
// printf("le_encrypt txt ");
// hexdump(plaintext, 16);
aes128_calc_cyphertext(key, plaintext, aes128_cyphertext);
printf("le_encrypt res ");
hexdump(aes128_cyphertext, 16);
// printf("le_encrypt res ");
// hexdump(aes128_cyphertext, 16);
}
return 0;
}
uint8_t *l2cap_get_outgoing_buffer(void){
printf("l2cap_get_outgoing_buffer\n");
return (uint8_t *)&l2cap_stack_buffer; // 8 bytes
}
uint16_t l2cap_max_mtu(void){
printf("l2cap_max_mtu\n");
return max_mtu;
}
void l2cap_register_fixed_channel(btstack_packet_handler_t packet_handler, uint16_t channel_id) {
le_data_handler = packet_handler;
}
@ -155,21 +168,22 @@ int l2cap_send_prepared_connectionless(uint16_t handle, uint16_t cid, uint16_t l
}
int l2cap_send_connectionless(uint16_t handle, uint16_t cid, uint8_t * buffer, uint16_t len){
printf("l2cap_send_connectionless\n");
uint8_t acl_buffer[len + 8];
// printf("l2cap_send_connectionless\n");
// 0 - Connection handle : PB=10 : BC=00
bt_store_16(acl_buffer, 0, handle | (2 << 12) | (0 << 14));
bt_store_16(packet_buffer, 0, handle | (2 << 12) | (0 << 14));
// 2 - ACL length
bt_store_16(acl_buffer, 2, len + 4);
bt_store_16(packet_buffer, 2, len + 4);
// 4 - L2CAP packet length
bt_store_16(acl_buffer, 4, len + 0);
bt_store_16(packet_buffer, 4, len + 0);
// 6 - L2CAP channel DEST
bt_store_16(acl_buffer, 6, cid);
bt_store_16(packet_buffer, 6, cid);
memcpy(&acl_buffer[8], buffer, len);
hci_dump_packet(HCI_ACL_DATA_PACKET, 0, &acl_buffer[0], len + 8);
memcpy(&packet_buffer[8], buffer, len);
hci_dump_packet(HCI_ACL_DATA_PACKET, 0, &packet_buffer[0], len + 8);
dump_packet(HCI_ACL_DATA_PACKET, packet_buffer, len + 8);
packet_buffer_len = len + 8;
return 0;
}

View File

@ -22,32 +22,79 @@
#include "l2cap.h"
#include "sm.h"
/*
SM: sending security request
SMP: generation method 0
p1 07 07 10 01 00 03 02 07 07 10 01 00 04 01 00 01
r 2F 04 82 84 72 46 9C 93 48 3F 27 0E EB D5 05 7A
t1 28 03 92 85 72 45 9E 94 4F 2F 26 0E EF D4 05 7B
p2 00 00 00 00 73 C9 68 5E 12 18 00 1B DC 07 32 EF
t3 CD FE D3 58 79 85 2C 84 A6 47 4D AD 7F 7B D0 87
c1! DA 42 76 BE B2 C0 17 A1 52 E3 96 C3 9A 8D E9 A9
p1 07 07 10 01 00 03 02 07 07 10 01 00 04 01 00 01
r 29 36 C0 5E F7 AC 43 D5 84 DC 1E 0F 45 06 D4 FD
t1 2E 31 D0 5F F7 AF 41 D2 83 CC 1F 0F 41 07 D4 FC
p2 00 00 00 00 73 C9 68 5E 12 18 00 1B DC 07 32 EF
t3 55 C2 AF B9 F9 95 5E 80 35 4D 48 B5 E4 BE D8 71
c1! C8 A9 70 70 A0 79 C5 48 BA 42 A9 0F 9A 87 5A 84
r1 2F 04 82 84 72 46 9C 93 48 3F 27 0E EB D5 05 7A
r2 29 36 C0 5E F7 AC 43 D5 84 DC 1E 0F 45 06 D4 FD
stk 30 95 98 99 12 1C 56 70 D1 D4 5F 8D 5F A2 36 D1
div 0xf1e2
y 0x45b9
ediv 0xb45b
ltk 73 30 38 B7 83 A3 C3 CF A1 E9 7A 04 0B D9 2F EF
Central Device DB adding type 1 - 73:C9:68:5E:12:18
irk 95 78 40 80 59 66 48 90 94 7F BB 92 53 91 7B C6
csrk 02 91 78 72 29 23 C5 F5 5F B1 99 94 42 5F 02 8D
*/
// test data
uint8_t test_command_packet_01[] = {
0x17, 0x20, 0x20, 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93,
0x92, 0x91, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, };
uint8_t test_command_packet_02[] = {
0x17, 0x20, 0x20, 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93,
0x92, 0x91, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, };
uint8_t test_acl_packet_03[] = {
0x40, 0x20, 0x0b, 0x00, 0x07, 0x00, 0x06, 0x00, 0x02, 0x03, 0x00, 0x01, 0x10, 0x07, 0x07, };
uint8_t test_command_packet_04[] = {
0x18, 0x20, 0x00, };
uint8_t test_command_packet_05[] = {
0x18, 0x20, 0x00, };
uint8_t test_command_packet_06[] = {
0x17, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7b, 0x05, 0xd4, 0xef, 0x0e, 0x26, 0x2f, 0x4f, 0x94, 0x9e, 0x45, 0x72, 0x85,
0x92, 0x03, 0x28, };
uint8_t test_command_packet_07[] = {
0x17, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x87, 0xd0, 0x7b, 0x7f, 0xad, 0x4d, 0x47, 0xa6, 0x84, 0x2c, 0x85, 0x79, 0x58,
0xd3, 0xfe, 0xcd, };
uint8_t test_acl_packet_08[] = {
0x40, 0x20, 0x15, 0x00, 0x11, 0x00, 0x06, 0x00, 0x03, 0xa9, 0xe9, 0x8d, 0x9a, 0xc3, 0x96, 0xe3,
0x52, 0xa1, 0x17, 0xc0, 0xb2, 0xbe, 0x76, 0x42, 0xda, };
uint8_t test_command_packet_09[] = {
0x17, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfc, 0xd4, 0x07, 0x41, 0x0f, 0x1f, 0xcc, 0x83, 0xd2, 0x41, 0xaf, 0xf7, 0x5f,
0xd0, 0x31, 0x2e, };
uint8_t test_command_packet_10[] = {
0x17, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x71, 0xd8, 0xbe, 0xe4, 0xb5, 0x48, 0x4d, 0x35, 0x80, 0x5e, 0x95, 0xf9, 0xb9,
0xaf, 0xc2, 0x55, };
uint8_t test_acl_packet_11[] = {
0x40, 0x20, 0x15, 0x00, 0x11, 0x00, 0x06, 0x00, 0x04, 0x7a, 0x05, 0xd5, 0xeb, 0x0e, 0x27, 0x3f,
0x48, 0x93, 0x9c, 0x46, 0x72, 0x84, 0x82, 0x04, 0x2f, };
uint8_t test_command_packet_12[] = {
0x17, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfd, 0xd4, 0x06, 0x45, 0x0f, 0x1e, 0xdc, 0x84, 0x7a, 0x05, 0xd5, 0xeb, 0x0e,
0x27, 0x3f, 0x48, };
uint8_t test_command_packet_13[] = {
0x1a, 0x20, 0x12, 0x40, 0x00, 0xd1, 0x36, 0xa2, 0x5f, 0x8d, 0x5f, 0xd4, 0xd1, 0x70, 0x56, 0x1c,
0x12, 0x99, 0x98, 0x95, 0x30, };
uint8_t test_command_packet_14[] = {
0x18, 0x20, 0x00, };
uint8_t test_command_packet_15[] = {
0x18, 0x20, 0x00, };
uint8_t test_command_packet_16[] = {
0x17, 0x20, 0x20, 0xc7, 0x29, 0x17, 0x92, 0x59, 0xb9, 0x8f, 0xaa, 0xa2, 0x0a, 0x32, 0x2a, 0x73,
0xc6, 0x4f, 0xb5, 0xcf, 0x10, 0x70, 0x5f, 0x3c, 0x2d, 0xe3, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, };
uint8_t test_command_packet_17[] = {
0x17, 0x20, 0x20, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33,
0x32, 0x31, 0x30, 0xe2, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, };
uint8_t test_acl_packet_18[] = {
0x40, 0x20, 0x15, 0x00, 0x11, 0x00, 0x06, 0x00, 0x06, 0xef, 0x2f, 0xd9, 0x0b, 0x04, 0x7a, 0xe9,
0xa1, 0xcf, 0xc3, 0xa3, 0x83, 0xb7, 0x38, 0x30, 0x73, };
uint8_t test_acl_packet_19[] = {
0x40, 0x20, 0x0f, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x07, 0x5b, 0xb4, 0xcf, 0x10, 0x70, 0x5f, 0x3c,
0x2d, 0xe3, 0xb3, };
uint8_t test_acl_packet_20[] = {
0x40, 0x20, 0x15, 0x00, 0x11, 0x00, 0x06, 0x00, 0x08, 0xe6, 0xea, 0xee, 0x60, 0x31, 0x7b, 0xfc,
0xa2, 0x3f, 0xa5, 0x79, 0x59, 0xe7, 0x41, 0xcf, 0xc7, };
uint8_t test_acl_packet_21[] = {
0x40, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x09, 0x00, 0xef, 0x32, 0x07, 0xdc, 0x1b, 0x00, };
uint8_t test_acl_packet_22[] = {
0x40, 0x20, 0x15, 0x00, 0x11, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
bd_addr_t test_device_addr = {0x34, 0xb1, 0xf7, 0xd1, 0x77, 0x9b};
@ -57,6 +104,8 @@ void aes128_report_result();
void mock_simulate_sm_data_packet(uint8_t * packet, uint16_t size);
void mock_simulate_command_complete(const hci_cmd_t *cmd);
void mock_simulate_connected();
uint8_t * mock_packet_buffer(void);
void mock_clear_packet_buffer(void);
void hexdump2(void const *data, int size){
int i;
@ -72,6 +121,11 @@ void CHECK_EQUAL_ARRAY(uint8_t * expected, uint8_t * actual, int size){
BYTES_EQUAL(expected[i], actual[i]);
}
}
#define CHECK_HCI_COMMAND(packet) { printf("check " #packet "\n") ; CHECK_EQUAL_ARRAY(packet, mock_packet_buffer(), sizeof(packet)); mock_clear_packet_buffer(); }
#define CHECK_ACL_PACKET(packet) { printf("check " #packet "\n") ; CHECK_EQUAL_ARRAY(packet, mock_packet_buffer(), sizeof(packet)); mock_clear_packet_buffer(); }
TEST_GROUP(GATTClient){
void setup(){
btstack_memory_init();
@ -82,7 +136,14 @@ TEST_GROUP(GATTClient){
mock_simulate_hci_state_working();
// expect le encrypt commmand
CHECK_HCI_COMMAND(test_command_packet_01);
aes128_report_result();
// expect le encrypt commmand
CHECK_HCI_COMMAND(test_command_packet_02);
aes128_report_result();
mock_simulate_connected();
@ -90,23 +151,115 @@ TEST_GROUP(GATTClient){
uint8_t test_pairing_request_command[] = { 0x01, 0x04, 0x00, 0x01, 0x10, 0x07, 0x07 };
mock_simulate_sm_data_packet(&test_pairing_request_command[0], sizeof(test_pairing_request_command));
// expect send pairing response command
CHECK_ACL_PACKET(test_acl_packet_03);
uint8_t test_pairing_confirm_command[] = { 0x03, 0x84, 0x5a, 0x87, 0x9a, 0x0f, 0xa9, 0x42, 0xba, 0x48, 0xc5, 0x79, 0xa0, 0x70, 0x70, 0xa9, 0xc8 };
mock_simulate_sm_data_packet(&test_pairing_confirm_command[0], sizeof(test_pairing_confirm_command));
// expect le random command
CHECK_HCI_COMMAND(test_command_packet_04);
uint8_t rand1_data_event[] = { 0x0e, 0x0c, 0x01, 0x18, 0x20, 0x00, 0x2f, 0x04, 0x82, 0x84, 0x72, 0x46, 0x9c, 0x93 };
mock_simulate_hci_event(&rand1_data_event[0], sizeof(rand1_data_event));
// expect le random command
CHECK_HCI_COMMAND(test_command_packet_05);
uint8_t rand2_data_event[] = { 0x0e, 0x0c,0x01, 0x18,0x20, 0x00,0x48, 0x3f,0x27, 0x0e,0xeb, 0xd5,0x05, 0x7a };
mock_simulate_hci_event(&rand2_data_event[0], sizeof(rand2_data_event));
// expect le encrypt command
CHECK_HCI_COMMAND(test_command_packet_06);
aes128_report_result();
// expect le encrypt command
CHECK_HCI_COMMAND(test_command_packet_07);
aes128_report_result();
// expect send paring confirm command
CHECK_ACL_PACKET(test_acl_packet_08);
uint8_t test_pairing_random_command[] ={0x04, 0xfd, 0xd4, 0x06, 0x45, 0x0f, 0x1e, 0xdc, 0x84, 0xd5, 0x43, 0xac, 0xf7, 0x5e, 0xc0, 0x36, 0x29};
mock_simulate_sm_data_packet(&test_pairing_random_command[0], sizeof(test_pairing_random_command));
// expect le encrypt command
CHECK_HCI_COMMAND(test_command_packet_09);
aes128_report_result();
// expect le encrypt command
CHECK_HCI_COMMAND(test_command_packet_10);
aes128_report_result();
// expect send pairing random command
CHECK_ACL_PACKET(test_acl_packet_11);
// NOTE: SM also triggered for wrong handle
uint8_t test_le_ltk_request[] = { 0x3e, 0x0d, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00 };
mock_simulate_hci_event(&test_le_ltk_request[0], sizeof(test_le_ltk_request));
// expect le encrypt command
CHECK_HCI_COMMAND(test_command_packet_12);
aes128_report_result();
// expect le ltk reply
CHECK_HCI_COMMAND(test_command_packet_13);
uint8_t test_ecnryption_change_event[] = { 0x08, 0x04, 0x00, 0x40, 0x00, 0x01 };
mock_simulate_hci_event(&test_ecnryption_change_event[0], sizeof(test_ecnryption_change_event));
// expect le random command
CHECK_HCI_COMMAND(test_command_packet_14);
uint8_t rand3_data_event[] = { 0x0e, 0x0c, 0x01, 0x18, 0x20, 0x00, 0xc0, 0x10, 0x70, 0x5f, 0x3c, 0x2d, 0xe3, 0xb3 };
mock_simulate_hci_event(&rand3_data_event[0], sizeof(rand3_data_event));
// expect le random command
CHECK_HCI_COMMAND(test_command_packet_15);
uint8_t rand4_data_event[] = { 0x0e, 0x0c, 0x01, 0x18, 0x20, 0x00, 0xf1, 0xe2, 0xbf, 0x7d, 0x84, 0x19, 0x32, 0x8b };
mock_simulate_hci_event(&rand4_data_event[0], sizeof(rand4_data_event));
// expect le encrypt command
CHECK_HCI_COMMAND(test_command_packet_16);
aes128_report_result();
// expect le encrypt command
CHECK_HCI_COMMAND(test_command_packet_17);
aes128_report_result();
uint8_t num_completed_packets_event[] = { 0x13, 0x05, 0x01, 0x4a, 0x00, 0x01, 00 };
// expect send LE SMP Encryption Information Command
CHECK_ACL_PACKET(test_acl_packet_18);
mock_simulate_hci_event(&num_completed_packets_event[0], sizeof(num_completed_packets_event));
// expect send LE SMP Master Identification Command
CHECK_ACL_PACKET(test_acl_packet_19);
mock_simulate_hci_event(&num_completed_packets_event[0], sizeof(num_completed_packets_event));
// expect send LE SMP Identity Information Command
CHECK_ACL_PACKET(test_acl_packet_20);
mock_simulate_hci_event(&num_completed_packets_event[0], sizeof(num_completed_packets_event));
// expect send LE SMP Identity Address Information Command
CHECK_ACL_PACKET(test_acl_packet_21);
mock_simulate_hci_event(&num_completed_packets_event[0], sizeof(num_completed_packets_event));
// expect send LE SMP Code Signing Information Command
CHECK_ACL_PACKET(test_acl_packet_22);
}
};