1 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 3 #include "uECC.h" 4 5 #include <stdio.h> 6 #include <string.h> 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdint.h> 11 #include <stdlib.h> 12 13 #include "btstack_debug.h" 14 15 typedef uint8_t sm_key24_t[3]; 16 typedef uint8_t sm_key56_t[7]; 17 typedef uint8_t sm_key_t[16]; 18 typedef uint8_t sm_key256_t[32]; 19 20 // P256 Set 1 21 static const char * set1_private_a_string = "3f49f6d4a3c55f3874c9b3e3d2103f504aff607beb40b7995899b8a6cd3c1abd"; 22 static const char * set1_private_b_string = "55188b3d32f6bb9a900afcfbeed4e72a59cb9ac2f19d7cfb6b4fdd49f47fc5fd"; 23 static const char * set1_public_a_string = \ 24 "20b003d2f297be2c5e2c83a7e9f9a5b9eff49111acf4fddbcc0301480e359de6" \ 25 "dc809c49652aeb6d63329abf5a52155c766345c28fed3024741c8ed01589d28b"; 26 static const char * set1_public_b_string = \ 27 "1ea1f0f01faf1d9609592284f19e4c0047b58afd8615a69f559077b22faaa190" \ 28 "4c55f33e429dad377356703a9ab85160472d1130e28e36765f89aff915b1214a"; 29 static const char * set1_dh_key_string = "ec0234a357c8ad05341010a60a397d9b99796b13b4f866f1868d34f373bfa698"; 30 31 // P256 Set 1 32 static const char * set2_private_a_string = "06a516693c9aa31a6084545d0c5db641b48572b97203ddffb7ac73f7d0457663"; 33 static const char * set2_private_b_string = "529aa0670d72cd6497502ed473502b037e8803b5c60829a5a3caa219505530ba"; 34 static const char * set2_public_a_string = \ 35 "2c31a47b5779809ef44cb5eaaf5c3e43d5f8faad4a8794cb987e9b03745c78dd" \ 36 "919512183898dfbecd52e2408e43871fd021109117bd3ed4eaf8437743715d4f"; 37 static const char * set2_public_b_string = \ 38 "f465e43ff23d3f1b9dc7dfc04da8758184dbc966204796eccf0d6cf5e16500cc" \ 39 "0201d048bcbbd899eeefc424164e33c201c2b010ca6b4d43a8a155cad8ecb279"; 40 static const char * set2_dh_key_string = "ab85843a2f6d883f62e5684b38e307335fe6e1945ecd19604105c6f23221eb69"; 41 42 uint32_t big_endian_read_32( const uint8_t * buffer, int pos) { 43 return ((uint32_t) buffer[(pos)+3]) | (((uint32_t)buffer[(pos)+2]) << 8) | (((uint32_t)buffer[(pos)+1]) << 16) | (((uint32_t) buffer[pos]) << 24); 44 } 45 46 void big_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value){ 47 buffer[pos++] = value >> 24; 48 buffer[pos++] = value >> 16; 49 buffer[pos++] = value >> 8; 50 buffer[pos++] = value; 51 } 52 53 static void hexdump_key(void *data, int size){ 54 if (size <= 0) return; 55 int i; 56 for (i=0; i<size;i++){ 57 printf("%02X", ((uint8_t *)data)[i]); 58 } 59 printf("\n"); 60 } 61 62 static int nibble_for_char(char c){ 63 if (c >= '0' && c <= '9') return c - '0'; 64 if (c >= 'a' && c <= 'f') return c - 'a' + 10; 65 if (c >= 'A' && c <= 'F') return c - 'F' + 10; 66 return -1; 67 } 68 69 static int parse_hex(uint8_t * buffer, const char * hex_string){ 70 int len = 0; 71 while (*hex_string){ 72 if (*hex_string == ' '){ 73 hex_string++; 74 continue; 75 } 76 int high_nibble = nibble_for_char(*hex_string++); 77 int low_nibble = nibble_for_char(*hex_string++); 78 int value = (high_nibble << 4) | low_nibble; 79 buffer[len++] = value; 80 } 81 return len; 82 } 83 84 85 static int test_generate_f_rng(uint8_t * buffer, unsigned size){ 86 // printf("test_generate_f_rng: size %u\n", (int)size); 87 while (size) { 88 *buffer++ = rand() & 0xff; 89 size--; 90 } 91 return 1; 92 } 93 94 int test_set1(void){ 95 uint8_t private1[uECC_BYTES]; 96 uint8_t private2[uECC_BYTES]; 97 uint8_t public1[uECC_BYTES * 2]; 98 uint8_t public1_computed[uECC_BYTES * 2]; 99 uint8_t public2[uECC_BYTES * 2]; 100 uint8_t secret1[uECC_BYTES]; 101 uint8_t secret2[uECC_BYTES]; 102 uint8_t secret[uECC_BYTES]; 103 104 parse_hex(private1, set1_private_a_string); 105 parse_hex(public1, set1_public_a_string); 106 parse_hex(private2, set1_private_b_string); 107 parse_hex(public2, set1_public_b_string); 108 parse_hex(secret, set1_dh_key_string); 109 110 if (!uECC_compute_public_key(private1, public1_computed)){ 111 printf("uECC_compute_public_key() failed\n"); 112 } 113 if (memcmp(public1, public1_computed, sizeof(public1_computed)) != 0) { 114 printf("Computed public key differs from test data!\n"); 115 printf("Computed key = "); 116 hexdump_key(public1_computed, uECC_BYTES * 2); 117 printf("Expected ke = "); 118 hexdump_key(public1, uECC_BYTES * 2); 119 return 0; 120 } 121 122 if (!uECC_shared_secret(public2, private1, secret1)) { 123 printf("shared_secret() failed (1)\n"); 124 return 0; 125 } 126 127 if (!uECC_shared_secret(public1, private2, secret2)) { 128 printf("shared_secret() failed (2)\n"); 129 return 0; 130 } 131 132 if (memcmp(secret1, secret2, sizeof(secret1)) != 0) { 133 printf("Shared secrets are not identical!\n"); 134 printf("Shared secret 1 = "); 135 hexdump_key(secret1, uECC_BYTES); 136 printf("Shared secret 2 = "); 137 hexdump_key(secret2, uECC_BYTES); 138 printf("Expected secret = "); hexdump_key(secret1, uECC_BYTES); 139 return 0; 140 } 141 // printf("Shared secret = "); hexdump_key(secret1, uECC_BYTES); 142 return 1; 143 } 144 145 int test_set2(void){ 146 uint8_t private1[uECC_BYTES]; 147 uint8_t private2[uECC_BYTES]; 148 uint8_t public1[uECC_BYTES * 2]; 149 uint8_t public1_computed[uECC_BYTES * 2]; 150 uint8_t public2[uECC_BYTES * 2]; 151 uint8_t secret1[uECC_BYTES]; 152 uint8_t secret2[uECC_BYTES]; 153 uint8_t secret[uECC_BYTES]; 154 155 parse_hex(private1, set2_private_a_string); 156 parse_hex(public1, set2_public_a_string); 157 parse_hex(private2, set2_private_b_string); 158 parse_hex(public2, set2_public_b_string); 159 parse_hex(secret, set2_dh_key_string); 160 161 if (!uECC_compute_public_key(private1, public1_computed)){ 162 printf("uECC_compute_public_key() failed\n"); 163 } 164 165 if (memcmp(public1, public1_computed, sizeof(public1_computed)) != 0) { 166 printf("Computed public key differs from test data!\n"); 167 printf("Computed key = "); 168 hexdump_key(public1_computed, uECC_BYTES * 2); 169 printf("Expected key = "); 170 hexdump_key(public1, uECC_BYTES * 2); 171 return 0; 172 } 173 174 if (!uECC_shared_secret(public2, private1, secret1)) { 175 printf("shared_secret() failed (1)\n"); 176 return 0; 177 } 178 179 if (!uECC_shared_secret(public1, private2, secret2)) { 180 printf("shared_secret() failed (2)\n"); 181 return 0; 182 } 183 184 if (memcmp(secret1, secret2, sizeof(secret1)) != 0) { 185 printf("Shared secrets are not identical!\n"); 186 printf("Shared secret 1 = "); 187 hexdump_key(secret1, uECC_BYTES); 188 printf("Shared secret 2 = "); 189 hexdump_key(secret2, uECC_BYTES); 190 printf("Expected secret = "); hexdump_key(secret1, uECC_BYTES); 191 return 0; 192 } 193 // printf("Shared secret = "); hexdump_key(secret1, uECC_BYTES); 194 return 1; 195 } 196 197 int test_generate(void){ 198 // use stdlib rand with fixed seed for testing 199 srand(0); 200 201 uint8_t d[uECC_BYTES]; 202 uint8_t q[uECC_BYTES * 2]; 203 204 if (!uECC_make_key(q, d)) { 205 printf("uECC_make_key() failed\n"); 206 return 1; 207 } 208 209 // print keypair 210 printf("d: "); hexdump_key(d, uECC_BYTES); 211 printf("X: "); hexdump_key(&q[00], uECC_BYTES); 212 printf("Y: "); hexdump_key(&q[16], uECC_BYTES); 213 214 // verify public key 215 if (!uECC_valid_public_key(q)){ 216 printf("uECC_valid_public_key() == 0 -> generated public key invalid\n"); 217 return 1; 218 } 219 220 // verify private key? 221 // TODO: 222 223 return 0; 224 } 225 226 int main(void){ 227 // check configuration 228 btstack_assert(uECC_curve() == uECC_secp256r1); 229 btstack_assert(uECC_bytes() == 32); 230 231 // check zero key is invalid 232 uint8_t q[uECC_BYTES * 2]; 233 memset(q, 0, sizeof(q)); 234 btstack_assert(uECC_valid_public_key(q) == 0); 235 236 // check key genration without rng 237 uint8_t d[uECC_BYTES]; 238 btstack_assert(uECC_make_key(q, d) == 0); 239 240 uECC_set_rng(&test_generate_f_rng); 241 test_set1(); 242 test_set2(); 243 test_generate(); 244 return 0; 245 } 246