1 /* 2 * CDDL HEADER START 3 * 4 * This file and its contents are supplied under the terms of the 5 * Common Development and Distribution License ("CDDL"), version 1.0. 6 * You may only use this file in accordance with the terms of version 7 * 1.0 of the CDDL. 8 * 9 * A full copy of the text of the CDDL should have accompanied this 10 * source. A copy of the CDDL is also available via the Internet at 11 * http://www.illumos.org/license/CDDL. 12 * 13 * CDDL HEADER END 14 */ 15 16 /* 17 * Copyright (c) 2017, Datto, Inc. All rights reserved. 18 */ 19 20 #include <stdio.h> 21 #include <strings.h> 22 #include <sys/crypto/icp.h> 23 #include <sys/sha2.h> 24 #include <sys/hkdf.h> 25 26 #define NELEMS(x) (sizeof (x) / sizeof ((x)[0])) 27 28 /* 29 * Byte arrays are given as char pointers so that they 30 * can be specified as strings. 31 */ 32 typedef struct hkdf_tv { 33 /* test vector input values */ 34 char *ikm; 35 uint_t ikm_len; 36 char *salt; 37 uint_t salt_len; 38 char *info; 39 uint_t info_len; 40 uint_t okm_len; 41 42 /* expected output */ 43 char *okm; 44 } hkdf_tv_t; 45 46 /* 47 * XXX Neither NIST nor IETF has published official test 48 * vectors for testing HKDF with SHA512. The following 49 * vectors should be updated if these are ever published. 50 * The current vectors were taken from: 51 * https://www.kullo.net/blog/hkdf-sha-512-test-vectors/ 52 */ 53 static hkdf_tv_t test_vectors[] = { 54 { 55 .ikm = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" 56 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" 57 "\x0b\x0b\x0b\x0b\x0b\x0b", 58 .ikm_len = 22, 59 .salt = "\x00\x01\x02\x03\x04\x05\x06\x07" 60 "\x08\x09\x0a\x0b\x0c", 61 .salt_len = 13, 62 .info = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7" 63 "\xf8\xf9", 64 .info_len = 10, 65 .okm_len = 42, 66 .okm = "\x83\x23\x90\x08\x6c\xda\x71\xfb" 67 "\x47\x62\x5b\xb5\xce\xb1\x68\xe4" 68 "\xc8\xe2\x6a\x1a\x16\xed\x34\xd9" 69 "\xfc\x7f\xe9\x2c\x14\x81\x57\x93" 70 "\x38\xda\x36\x2c\xb8\xd9\xf9\x25" 71 "\xd7\xcb", 72 }, 73 { 74 .ikm = "\x00\x01\x02\x03\x04\x05\x06\x07" 75 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" 76 "\x10\x11\x12\x13\x14\x15\x16\x17" 77 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" 78 "\x20\x21\x22\x23\x24\x25\x26\x27" 79 "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" 80 "\x30\x31\x32\x33\x34\x35\x36\x37" 81 "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" 82 "\x40\x41\x42\x43\x44\x45\x46\x47" 83 "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", 84 .ikm_len = 80, 85 .salt = "\x60\x61\x62\x63\x64\x65\x66\x67" 86 "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" 87 "\x70\x71\x72\x73\x74\x75\x76\x77" 88 "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" 89 "\x80\x81\x82\x83\x84\x85\x86\x87" 90 "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" 91 "\x90\x91\x92\x93\x94\x95\x96\x97" 92 "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" 93 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7" 94 "\xa8\xa9\xaa\xab\xac\xad\xae\xaf", 95 .salt_len = 80, 96 .info = "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7" 97 "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" 98 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" 99 "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" 100 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7" 101 "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" 102 "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7" 103 "\xe8\xe9\xea\xeb\xec\xed\xee\xef" 104 "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7" 105 "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", 106 .info_len = 80, 107 .okm_len = 42, 108 .okm = "\xce\x6c\x97\x19\x28\x05\xb3\x46" 109 "\xe6\x16\x1e\x82\x1e\xd1\x65\x67" 110 "\x3b\x84\xf4\x00\xa2\xb5\x14\xb2" 111 "\xfe\x23\xd8\x4c\xd1\x89\xdd\xf1" 112 "\xb6\x95\xb4\x8c\xbd\x1c\x83\x88" 113 "\x44\x11\x37\xb3\xce\x28\xf1\x6a" 114 "\xa6\x4b\xa3\x3b\xa4\x66\xb2\x4d" 115 "\xf6\xcf\xcb\x02\x1e\xcf\xf2\x35" 116 "\xf6\xa2\x05\x6c\xe3\xaf\x1d\xe4" 117 "\x4d\x57\x20\x97\xa8\x50\x5d\x9e" 118 "\x7a\x93", 119 }, 120 { 121 .ikm = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" 122 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" 123 "\x0b\x0b\x0b\x0b\x0b\x0b", 124 .ikm_len = 22, 125 .salt = NULL, 126 .salt_len = 0, 127 .info = NULL, 128 .info_len = 0, 129 .okm_len = 42, 130 .okm = "\xf5\xfa\x02\xb1\x82\x98\xa7\x2a" 131 "\x8c\x23\x89\x8a\x87\x03\x47\x2c" 132 "\x6e\xb1\x79\xdc\x20\x4c\x03\x42" 133 "\x5c\x97\x0e\x3b\x16\x4b\xf9\x0f" 134 "\xff\x22\xd0\x48\x36\xd0\xe2\x34" 135 "\x3b\xac", 136 }, 137 { 138 .ikm = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" 139 "\x0b\x0b\x0b", 140 .ikm_len = 11, 141 .salt = "\x00\x01\x02\x03\x04\x05\x06\x07" 142 "\x08\x09\x0a\x0b\x0c", 143 .salt_len = 13, 144 .info = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7" 145 "\xf8\xf9", 146 .info_len = 10, 147 .okm_len = 42, 148 .okm = "\x74\x13\xe8\x99\x7e\x02\x06\x10" 149 "\xfb\xf6\x82\x3f\x2c\xe1\x4b\xff" 150 "\x01\x87\x5d\xb1\xca\x55\xf6\x8c" 151 "\xfc\xf3\x95\x4d\xc8\xaf\xf5\x35" 152 "\x59\xbd\x5e\x30\x28\xb0\x80\xf7" 153 "\xc0\x68", 154 }, 155 { 156 .ikm = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" 157 "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" 158 "\x0c\x0c\x0c\x0c\x0c\x0c", 159 .ikm_len = 22, 160 .salt = NULL, 161 .salt_len = 0, 162 .info = NULL, 163 .info_len = 0, 164 .okm_len = 42, 165 .okm = "\x14\x07\xd4\x60\x13\xd9\x8b\xc6" 166 "\xde\xce\xfc\xfe\xe5\x5f\x0f\x90" 167 "\xb0\xc7\xf6\x3d\x68\xeb\x1a\x80" 168 "\xea\xf0\x7e\x95\x3c\xfc\x0a\x3a" 169 "\x52\x40\xa1\x55\xd6\xe4\xda\xa9" 170 "\x65\xbb", 171 }, 172 }; 173 174 static void 175 hexdump(char *str, uint8_t *src, uint_t len) 176 { 177 int i; 178 179 printf("\t%s\t", str); 180 for (i = 0; i < len; i++) { 181 printf("%02x", src[i] & 0xff); 182 } 183 printf("\n"); 184 } 185 186 static int 187 run_test(int i, hkdf_tv_t *tv) 188 { 189 int ret; 190 uint8_t okey[SHA512_DIGEST_LENGTH]; 191 192 printf("TEST %d:\t", i); 193 194 ret = hkdf_sha512((uint8_t *)tv->ikm, tv->ikm_len, (uint8_t *)tv->salt, 195 tv->salt_len, (uint8_t *)tv->info, tv->info_len, okey, tv->okm_len); 196 if (ret != 0) { 197 printf("HKDF failed with error code %d\n", ret); 198 return (ret); 199 } 200 201 if (bcmp(okey, tv->okm, tv->okm_len) != 0) { 202 printf("Output Mismatch\n"); 203 hexdump("Expected:", (uint8_t *)tv->okm, tv->okm_len); 204 hexdump("Actual: ", okey, tv->okm_len); 205 return (1); 206 } 207 208 printf("Passed\n"); 209 210 return (0); 211 } 212 213 int 214 main(int argc, char **argv) 215 { 216 int ret, i; 217 218 icp_init(); 219 220 for (i = 0; i < NELEMS(test_vectors); i++) { 221 ret = run_test(i, &test_vectors[i]); 222 if (ret != 0) 223 break; 224 } 225 226 icp_fini(); 227 228 if (ret == 0) { 229 printf("All tests passed successfully.\n"); 230 return (0); 231 } else { 232 printf("Test failed.\n"); 233 return (1); 234 } 235 } 236