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