1 /* 2 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <err.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <openssl/chacha.h> 23 24 struct chacha_tv { 25 const char *desc; 26 const unsigned char key[32]; 27 const unsigned char iv[8]; 28 const size_t len; 29 const unsigned char out[512]; 30 }; 31 32 /* 33 * Test vectors from: 34 * http://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01 35 */ 36 struct chacha_tv chacha_test_vectors[] = { 37 { 38 "TC1: All zero key and IV", 39 { 40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 }, 45 { 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 }, 48 64, 49 { 50 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, 51 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, 52 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, 53 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, 54 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, 55 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, 56 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, 57 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86, 58 }, 59 }, 60 { 61 "TC2: Single bit in key set, all zero IV", 62 { 63 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 }, 68 { 69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 }, 71 64, 72 { 73 0xc5, 0xd3, 0x0a, 0x7c, 0xe1, 0xec, 0x11, 0x93, 74 0x78, 0xc8, 0x4f, 0x48, 0x7d, 0x77, 0x5a, 0x85, 75 0x42, 0xf1, 0x3e, 0xce, 0x23, 0x8a, 0x94, 0x55, 76 0xe8, 0x22, 0x9e, 0x88, 0x8d, 0xe8, 0x5b, 0xbd, 77 0x29, 0xeb, 0x63, 0xd0, 0xa1, 0x7a, 0x5b, 0x99, 78 0x9b, 0x52, 0xda, 0x22, 0xbe, 0x40, 0x23, 0xeb, 79 0x07, 0x62, 0x0a, 0x54, 0xf6, 0xfa, 0x6a, 0xd8, 80 0x73, 0x7b, 0x71, 0xeb, 0x04, 0x64, 0xda, 0xc0, 81 }, 82 }, 83 { 84 "TC3: Single bit in IV set, all zero key", 85 { 86 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 87 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 88 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 89 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 90 }, 91 { 92 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 93 }, 94 64, 95 { 96 0xd9, 0xbf, 0x3f, 0x6b, 0xce, 0x6e, 0xd0, 0xb5, 97 0x42, 0x54, 0x55, 0x77, 0x67, 0xfb, 0x57, 0x44, 98 0x3d, 0xd4, 0x77, 0x89, 0x11, 0xb6, 0x06, 0x05, 99 0x5c, 0x39, 0xcc, 0x25, 0xe6, 0x74, 0xb8, 0x36, 100 0x3f, 0xea, 0xbc, 0x57, 0xfd, 0xe5, 0x4f, 0x79, 101 0x0c, 0x52, 0xc8, 0xae, 0x43, 0x24, 0x0b, 0x79, 102 0xd4, 0x90, 0x42, 0xb7, 0x77, 0xbf, 0xd6, 0xcb, 103 0x80, 0xe9, 0x31, 0x27, 0x0b, 0x7f, 0x50, 0xeb, 104 }, 105 }, 106 { 107 "TC4: All bits in key and IV are set", 108 { 109 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 110 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 111 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 112 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 113 }, 114 { 115 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 116 }, 117 64, 118 { 119 0xaf, 0xf7, 0x41, 0x82, 0x93, 0xf3, 0xa5, 0x53, 120 0x89, 0x4b, 0x1e, 0x74, 0x84, 0xbd, 0x1e, 0x8e, 121 0xde, 0x19, 0x6e, 0xce, 0xd5, 0xa1, 0xd6, 0x81, 122 0x4d, 0xe3, 0x70, 0x91, 0xe0, 0x7e, 0x07, 0x6e, 123 0x34, 0xbb, 0xba, 0x81, 0x07, 0xa6, 0x86, 0xc9, 124 0x82, 0x85, 0x0f, 0x0a, 0x73, 0x53, 0x94, 0x0d, 125 0x40, 0xdb, 0x1a, 0xb0, 0xb5, 0x76, 0x5b, 0x78, 126 0xb4, 0xcf, 0x47, 0x3d, 0x94, 0x85, 0xa3, 0xdd, 127 }, 128 }, 129 { 130 "TC5: Every even bit set in key and IV", 131 { 132 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 133 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 134 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 135 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 136 }, 137 { 138 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 139 }, 140 64, 141 { 142 0xbe, 0xa9, 0x41, 0x1a, 0xa4, 0x53, 0xc5, 0x43, 143 0x4a, 0x5a, 0xe8, 0xc9, 0x28, 0x62, 0xf5, 0x64, 144 0x39, 0x68, 0x55, 0xa9, 0xea, 0x6e, 0x22, 0xd6, 145 0xd3, 0xb5, 0x0a, 0xe1, 0xb3, 0x66, 0x33, 0x11, 146 0xa4, 0xa3, 0x60, 0x6c, 0x67, 0x1d, 0x60, 0x5c, 147 0xe1, 0x6c, 0x3a, 0xec, 0xe8, 0xe6, 0x1e, 0xa1, 148 0x45, 0xc5, 0x97, 0x75, 0x01, 0x7b, 0xee, 0x2f, 149 0xa6, 0xf8, 0x8a, 0xfc, 0x75, 0x80, 0x69, 0xf7, 150 }, 151 }, 152 { 153 "TC6: Every odd bit set in key and IV", 154 { 155 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 156 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 157 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 158 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 159 }, 160 { 161 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 162 }, 163 64, 164 { 165 0x9a, 0xa2, 0xa9, 0xf6, 0x56, 0xef, 0xde, 0x5a, 166 0xa7, 0x59, 0x1c, 0x5f, 0xed, 0x4b, 0x35, 0xae, 167 0xa2, 0x89, 0x5d, 0xec, 0x7c, 0xb4, 0x54, 0x3b, 168 0x9e, 0x9f, 0x21, 0xf5, 0xe7, 0xbc, 0xbc, 0xf3, 169 0xc4, 0x3c, 0x74, 0x8a, 0x97, 0x08, 0x88, 0xf8, 170 0x24, 0x83, 0x93, 0xa0, 0x9d, 0x43, 0xe0, 0xb7, 171 0xe1, 0x64, 0xbc, 0x4d, 0x0b, 0x0f, 0xb2, 0x40, 172 0xa2, 0xd7, 0x21, 0x15, 0xc4, 0x80, 0x89, 0x06, 173 }, 174 }, 175 { 176 "TC7: Sequence patterns in key and IV", 177 { 178 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 179 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 180 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 181 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 182 }, 183 { 184 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, 185 }, 186 64, 187 { 188 0x9f, 0xad, 0xf4, 0x09, 0xc0, 0x08, 0x11, 0xd0, 189 0x04, 0x31, 0xd6, 0x7e, 0xfb, 0xd8, 0x8f, 0xba, 190 0x59, 0x21, 0x8d, 0x5d, 0x67, 0x08, 0xb1, 0xd6, 191 0x85, 0x86, 0x3f, 0xab, 0xbb, 0x0e, 0x96, 0x1e, 192 0xea, 0x48, 0x0f, 0xd6, 0xfb, 0x53, 0x2b, 0xfd, 193 0x49, 0x4b, 0x21, 0x51, 0x01, 0x50, 0x57, 0x42, 194 0x3a, 0xb6, 0x0a, 0x63, 0xfe, 0x4f, 0x55, 0xf7, 195 0xa2, 0x12, 0xe2, 0x16, 0x7c, 0xca, 0xb9, 0x31, 196 }, 197 }, 198 { 199 "TC8: key: 'All your base are belong to us!, IV: 'IETF2013'", 200 { 201 0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78, 202 0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35, 203 0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb, 204 0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d, 205 }, 206 { 207 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21, 208 }, 209 64, 210 { 211 0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9, 212 0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06, 213 0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00, 214 0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf, 215 0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd, 216 0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f, 217 0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f, 218 0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92, 219 }, 220 }, 221 }; 222 223 #define N_VECTORS (sizeof(chacha_test_vectors) / sizeof(*chacha_test_vectors)) 224 225 /* Single-shot ChaCha20 using CRYPTO_chacha_20 interface. */ 226 static void 227 crypto_chacha_20_test(struct chacha_tv *tv, unsigned char *out, 228 unsigned char *in) 229 { 230 CRYPTO_chacha_20(out, in, tv->len, tv->key, tv->iv, 0); 231 } 232 233 /* Single-shot ChaCha20 using the ChaCha interface. */ 234 static void 235 chacha_ctx_full_test(struct chacha_tv *tv, unsigned char *out, 236 unsigned char *in) 237 { 238 ChaCha_ctx ctx; 239 240 ChaCha_set_key(&ctx, tv->key, 256); 241 ChaCha_set_iv(&ctx, tv->iv, NULL); 242 ChaCha(&ctx, out, in, tv->len); 243 } 244 245 /* ChaCha20 with partial writes using the Chacha interface. */ 246 static void 247 chacha_ctx_partial_test(struct chacha_tv *tv, unsigned char *out, 248 unsigned char *in) 249 { 250 ChaCha_ctx ctx; 251 int len, size = 0; 252 253 ChaCha_set_key(&ctx, tv->key, 256); 254 ChaCha_set_iv(&ctx, tv->iv, NULL); 255 len = tv->len - 1; 256 while (len > 1) { 257 size = len / 2; 258 ChaCha(&ctx, out, in, size); 259 in += size; 260 out += size; 261 len -= size; 262 } 263 ChaCha(&ctx, out, in, len + 1); 264 } 265 266 /* ChaCha20 with single byte writes using the Chacha interface. */ 267 static void 268 chacha_ctx_single_test(struct chacha_tv *tv, unsigned char *out, 269 unsigned char *in) 270 { 271 ChaCha_ctx ctx; 272 size_t i; 273 274 ChaCha_set_key(&ctx, tv->key, 256); 275 ChaCha_set_iv(&ctx, tv->iv, NULL); 276 for (i = 0; i < tv->len; i++) 277 ChaCha(&ctx, out + i, in + i, 1); 278 } 279 280 struct chacha_test_function { 281 char *name; 282 void (*func)(struct chacha_tv *, unsigned char *, unsigned char *); 283 }; 284 285 struct chacha_test_function chacha_test_functions[] = { 286 {"crypto_chacha_20_test", crypto_chacha_20_test}, 287 {"chacha_ctx_full_test", chacha_ctx_full_test}, 288 {"chacha_ctx_partial_test", chacha_ctx_partial_test}, 289 {"chacha_ctx_single_test", chacha_ctx_single_test}, 290 }; 291 292 #define N_FUNCS (sizeof(chacha_test_functions) / sizeof(*chacha_test_functions)) 293 294 int 295 main(int argc, char **argv) 296 { 297 struct chacha_tv *tv; 298 unsigned char *in, *out; 299 size_t i, j, k; 300 int failed = 0; 301 302 for (i = 0; i < N_VECTORS; i++) { 303 tv = &chacha_test_vectors[i]; 304 305 for (j = 0; j < N_FUNCS; j++) { 306 in = calloc(1, tv->len); 307 if (in == NULL) 308 errx(1, "calloc in"); 309 out = calloc(1, tv->len); 310 if (out == NULL) 311 errx(1, "calloc out"); 312 313 chacha_test_functions[j].func(tv, out, in); 314 315 if (memcmp(out, tv->out, tv->len) != 0) { 316 printf("ChaCha %s failed for \"%s\"!\n", 317 chacha_test_functions[j].name, tv->desc); 318 319 printf("Got:\t"); 320 for (k = 0; k < tv->len; k++) 321 printf("%2.2x", out[k]); 322 printf("\n"); 323 324 printf("Want:\t"); 325 for (k = 0; k < tv->len; k++) 326 printf("%2.2x", tv->out[k]); 327 printf("\n"); 328 329 failed = 1; 330 } 331 332 free(in); 333 free(out); 334 } 335 } 336 337 return failed; 338 } 339