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