1 /* $OpenBSD: chachapoly_test.c,v 1.1 2015/11/03 01:46:08 mikeb Exp $ */ 2 3 /* 4 * Copyright (c) 2010,2015 Mike Belopuhov <mikeb@openbsd.org> 5 * Copyright (c) 2005 Markus Friedl <markus@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/param.h> 21 #include <crypto/chachapoly.h> 22 #include <err.h> 23 #include <errno.h> 24 #include <string.h> 25 #include <stdlib.h> 26 #include <stdio.h> 27 28 int debug = 0; 29 30 enum { TST_KEY, TST_IV, TST_AAD, TST_PLAIN, TST_CIPHER, TST_TAG, TST_NUM }; 31 32 struct { 33 char *data[TST_NUM]; 34 } tests[] = { 35 /* Chacha20, counter=1 test vectors */ 36 37 /* Test vector from RFC7539 2.4.2 */ 38 { 39 /* key + salt */ 40 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " 41 "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f " 42 "00 00 00 00", 43 /* iv */ 44 "00 00 00 4a 00 00 00 00", 45 /* aad */ 46 NULL, 47 /* plaintext */ 48 "4c 61 64 69 65 73 20 61 6e 64 20 47 65 6e 74 6c " 49 "65 6d 65 6e 20 6f 66 20 74 68 65 20 63 6c 61 73 " 50 "73 20 6f 66 20 27 39 39 3a 20 49 66 20 49 20 63 " 51 "6f 75 6c 64 20 6f 66 66 65 72 20 79 6f 75 20 6f " 52 "6e 6c 79 20 6f 6e 65 20 74 69 70 20 66 6f 72 20 " 53 "74 68 65 20 66 75 74 75 72 65 2c 20 73 75 6e 73 " 54 "63 72 65 65 6e 20 77 6f 75 6c 64 20 62 65 20 69 " 55 "74 2e", 56 /* ciphertext */ 57 "6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81 " 58 "e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b " 59 "f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57 " 60 "16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8 " 61 "07 ca 0d bf 50 0d 6a 61 56 a3 8e 08 8a 22 b6 5e " 62 "52 bc 51 4d 16 cc f8 06 81 8c e9 1a b7 79 37 36 " 63 "5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42 " 64 "87 4d", 65 /* tag */ 66 NULL 67 }, 68 69 /* Test vector#2 from RFC7539 A.2 */ 70 { 71 /* key + salt */ 72 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " 73 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 " 74 "00 00 00 00", 75 /* iv */ 76 "00 00 00 00 00 00 00 02", 77 /* aad */ 78 NULL, 79 /* plaintext */ 80 "41 6e 79 20 73 75 62 6d 69 73 73 69 6f 6e 20 74 " 81 "6f 20 74 68 65 20 49 45 54 46 20 69 6e 74 65 6e " 82 "64 65 64 20 62 79 20 74 68 65 20 43 6f 6e 74 72 " 83 "69 62 75 74 6f 72 20 66 6f 72 20 70 75 62 6c 69 " 84 "63 61 74 69 6f 6e 20 61 73 20 61 6c 6c 20 6f 72 " 85 "20 70 61 72 74 20 6f 66 20 61 6e 20 49 45 54 46 " 86 "20 49 6e 74 65 72 6e 65 74 2d 44 72 61 66 74 20 " 87 "6f 72 20 52 46 43 20 61 6e 64 20 61 6e 79 20 73 " 88 "74 61 74 65 6d 65 6e 74 20 6d 61 64 65 20 77 69 " 89 "74 68 69 6e 20 74 68 65 20 63 6f 6e 74 65 78 74 " 90 "20 6f 66 20 61 6e 20 49 45 54 46 20 61 63 74 69 " 91 "76 69 74 79 20 69 73 20 63 6f 6e 73 69 64 65 72 " 92 "65 64 20 61 6e 20 22 49 45 54 46 20 43 6f 6e 74 " 93 "72 69 62 75 74 69 6f 6e 22 2e 20 53 75 63 68 20 " 94 "73 74 61 74 65 6d 65 6e 74 73 20 69 6e 63 6c 75 " 95 "64 65 20 6f 72 61 6c 20 73 74 61 74 65 6d 65 6e " 96 "74 73 20 69 6e 20 49 45 54 46 20 73 65 73 73 69 " 97 "6f 6e 73 2c 20 61 73 20 77 65 6c 6c 20 61 73 20 " 98 "77 72 69 74 74 65 6e 20 61 6e 64 20 65 6c 65 63 " 99 "74 72 6f 6e 69 63 20 63 6f 6d 6d 75 6e 69 63 61 " 100 "74 69 6f 6e 73 20 6d 61 64 65 20 61 74 20 61 6e " 101 "79 20 74 69 6d 65 20 6f 72 20 70 6c 61 63 65 2c " 102 "20 77 68 69 63 68 20 61 72 65 20 61 64 64 72 65 " 103 "73 73 65 64 20 74 6f", 104 /* ciphertext */ 105 "a3 fb f0 7d f3 fa 2f de 4f 37 6c a2 3e 82 73 70 " 106 "41 60 5d 9f 4f 4f 57 bd 8c ff 2c 1d 4b 79 55 ec " 107 "2a 97 94 8b d3 72 29 15 c8 f3 d3 37 f7 d3 70 05 " 108 "0e 9e 96 d6 47 b7 c3 9f 56 e0 31 ca 5e b6 25 0d " 109 "40 42 e0 27 85 ec ec fa 4b 4b b5 e8 ea d0 44 0e " 110 "20 b6 e8 db 09 d8 81 a7 c6 13 2f 42 0e 52 79 50 " 111 "42 bd fa 77 73 d8 a9 05 14 47 b3 29 1c e1 41 1c " 112 "68 04 65 55 2a a6 c4 05 b7 76 4d 5e 87 be a8 5a " 113 "d0 0f 84 49 ed 8f 72 d0 d6 62 ab 05 26 91 ca 66 " 114 "42 4b c8 6d 2d f8 0e a4 1f 43 ab f9 37 d3 25 9d " 115 "c4 b2 d0 df b4 8a 6c 91 39 dd d7 f7 69 66 e9 28 " 116 "e6 35 55 3b a7 6c 5c 87 9d 7b 35 d4 9e b2 e6 2b " 117 "08 71 cd ac 63 89 39 e2 5e 8a 1e 0e f9 d5 28 0f " 118 "a8 ca 32 8b 35 1c 3c 76 59 89 cb cf 3d aa 8b 6c " 119 "cc 3a af 9f 39 79 c9 2b 37 20 fc 88 dc 95 ed 84 " 120 "a1 be 05 9c 64 99 b9 fd a2 36 e7 e8 18 b0 4b 0b " 121 "c3 9c 1e 87 6b 19 3b fe 55 69 75 3f 88 12 8c c0 " 122 "8a aa 9b 63 d1 a1 6f 80 ef 25 54 d7 18 9c 41 1f " 123 "58 69 ca 52 c5 b8 3f a3 6f f2 16 b9 c1 d3 00 62 " 124 "be bc fd 2d c5 bc e0 91 19 34 fd a7 9a 86 f6 e6 " 125 "98 ce d7 59 c3 ff 9b 64 77 33 8f 3d a4 f9 cd 85 " 126 "14 ea 99 82 cc af b3 41 b2 38 4d d9 02 f3 d1 ab " 127 "7a c6 1d d2 9c 6f 21 ba 5b 86 2f 37 30 e3 7c fd " 128 "c4 fd 80 6c 22 f2 21", 129 /* tag */ 130 NULL 131 }, 132 133 /* Poly1305 test vectors */ 134 135 /* Test vector from RFC7539 2.8.2 */ 136 { 137 /* key + salt */ 138 "80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f " 139 "90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f " 140 "07 00 00 00", 141 /* iv */ 142 "40 41 42 43 44 45 46 47", 143 /* aad */ 144 "50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7", 145 /* plaintext */ 146 "4c 61 64 69 65 73 20 61 6e 64 20 47 65 6e 74 6c " 147 "65 6d 65 6e 20 6f 66 20 74 68 65 20 63 6c 61 73 " 148 "73 20 6f 66 20 27 39 39 3a 20 49 66 20 49 20 63 " 149 "6f 75 6c 64 20 6f 66 66 65 72 20 79 6f 75 20 6f " 150 "6e 6c 79 20 6f 6e 65 20 74 69 70 20 66 6f 72 20 " 151 "74 68 65 20 66 75 74 75 72 65 2c 20 73 75 6e 73 " 152 "63 72 65 65 6e 20 77 6f 75 6c 64 20 62 65 20 69 " 153 "74 2e", 154 /* ciphertext */ 155 "d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2 " 156 "a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6 " 157 "3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b " 158 "1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 36 " 159 "92 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58 " 160 "fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc " 161 "3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b " 162 "61 16", 163 /* tag */ 164 "1a e1 0b 59 4f 09 e2 6a 7e 90 2e cb d0 60 06 91" 165 }, 166 167 /* Test vector from RFC7539 Appendix A.5 */ 168 { 169 /* key + salt */ 170 "1c 92 40 a5 eb 55 d3 8a f3 33 88 86 04 f6 b5 f0 " 171 "47 39 17 c1 40 2b 80 09 9d ca 5c bc 20 70 75 c0 " 172 "00 00 00 00", 173 /* iv */ 174 "01 02 03 04 05 06 07 08", 175 /* aad */ 176 "f3 33 88 86 00 00 00 00 00 00 4e 91", 177 /* plaintext */ 178 "49 6e 74 65 72 6e 65 74 2d 44 72 61 66 74 73 20 " 179 "61 72 65 20 64 72 61 66 74 20 64 6f 63 75 6d 65 " 180 "6e 74 73 20 76 61 6c 69 64 20 66 6f 72 20 61 20 " 181 "6d 61 78 69 6d 75 6d 20 6f 66 20 73 69 78 20 6d " 182 "6f 6e 74 68 73 20 61 6e 64 20 6d 61 79 20 62 65 " 183 "20 75 70 64 61 74 65 64 2c 20 72 65 70 6c 61 63 " 184 "65 64 2c 20 6f 72 20 6f 62 73 6f 6c 65 74 65 64 " 185 "20 62 79 20 6f 74 68 65 72 20 64 6f 63 75 6d 65 " 186 "6e 74 73 20 61 74 20 61 6e 79 20 74 69 6d 65 2e " 187 "20 49 74 20 69 73 20 69 6e 61 70 70 72 6f 70 72 " 188 "69 61 74 65 20 74 6f 20 75 73 65 20 49 6e 74 65 " 189 "72 6e 65 74 2d 44 72 61 66 74 73 20 61 73 20 72 " 190 "65 66 65 72 65 6e 63 65 20 6d 61 74 65 72 69 61 " 191 "6c 20 6f 72 20 74 6f 20 63 69 74 65 20 74 68 65 " 192 "6d 20 6f 74 68 65 72 20 74 68 61 6e 20 61 73 20 " 193 "2f e2 80 9c 77 6f 72 6b 20 69 6e 20 70 72 6f 67 " 194 "72 65 73 73 2e 2f e2 80 9d", 195 /* ciphertext */ 196 "64 a0 86 15 75 86 1a f4 60 f0 62 c7 9b e6 43 bd " 197 "5e 80 5c fd 34 5c f3 89 f1 08 67 0a c7 6c 8c b2 " 198 "4c 6c fc 18 75 5d 43 ee a0 9e e9 4e 38 2d 26 b0 " 199 "bd b7 b7 3c 32 1b 01 00 d4 f0 3b 7f 35 58 94 cf " 200 "33 2f 83 0e 71 0b 97 ce 98 c8 a8 4a bd 0b 94 81 " 201 "14 ad 17 6e 00 8d 33 bd 60 f9 82 b1 ff 37 c8 55 " 202 "97 97 a0 6e f4 f0 ef 61 c1 86 32 4e 2b 35 06 38 " 203 "36 06 90 7b 6a 7c 02 b0 f9 f6 15 7b 53 c8 67 e4 " 204 "b9 16 6c 76 7b 80 4d 46 a5 9b 52 16 cd e7 a4 e9 " 205 "90 40 c5 a4 04 33 22 5e e2 82 a1 b0 a0 6c 52 3e " 206 "af 45 34 d7 f8 3f a1 15 5b 00 47 71 8c bc 54 6a " 207 "0d 07 2b 04 b3 56 4e ea 1b 42 22 73 f5 48 27 1a " 208 "0b b2 31 60 53 fa 76 99 19 55 eb d6 31 59 43 4e " 209 "ce bb 4e 46 6d ae 5a 10 73 a6 72 76 27 09 7a 10 " 210 "49 e6 17 d9 1d 36 10 94 fa 68 f0 ff 77 98 71 30 " 211 "30 5b ea ba 2e da 04 df 99 7b 71 4d 6c 6f 2c 29 " 212 "a6 ad 5c b4 02 2b 02 70 9b", 213 /* tag */ 214 "ee ad 9d 67 89 0c bb 22 39 23 36 fe a1 85 1f 38" 215 }, 216 217 /* Test vector from RFC7634 Appendix A */ 218 { 219 /* key + salt */ 220 "80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f " 221 "90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f " 222 "a0 a1 a2 a3", 223 /* iv */ 224 "10 11 12 13 14 15 16 17", 225 /* aad */ 226 "01 02 03 04 00 00 00 05", 227 /* plaintext */ 228 "45 00 00 54 a6 f2 00 00 40 01 e7 78 c6 33 64 05 " 229 "c0 00 02 05 08 00 5b 7a 3a 08 00 00 55 3b ec 10 " 230 "00 07 36 27 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 " 231 "14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 " 232 "24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 " 233 "34 35 36 37 01 02 02 04", 234 /* ciphertext */ 235 "24 03 94 28 b9 7f 41 7e 3c 13 75 3a 4f 05 08 7b " 236 "67 c3 52 e6 a7 fa b1 b9 82 d4 66 ef 40 7a e5 c6 " 237 "14 ee 80 99 d5 28 44 eb 61 aa 95 df ab 4c 02 f7 " 238 "2a a7 1e 7c 4c 4f 64 c9 be fe 2f ac c6 38 e8 f3 " 239 "cb ec 16 3f ac 46 9b 50 27 73 f6 fb 94 e6 64 da " 240 "91 65 b8 28 29 f6 41 e0", 241 /* tag */ 242 "76 aa a8 26 6b 7f b0 f7 b1 1b 36 99 07 e1 ad 43" 243 }, 244 245 /* Test vector from RFC7634 Appendix B */ 246 { 247 /* key + salt */ 248 "80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f " 249 "90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f " 250 "a0 a1 a2 a3", 251 /* iv */ 252 "10 11 12 13 14 15 16 17", 253 /* aad */ 254 "c0 c1 c2 c3 c4 c5 c6 c7 d0 d1 d2 d3 d4 d5 d6 d7 " 255 "2e 20 25 00 00 00 00 09 00 00 00 45 29 00 00 29", 256 /* plaintext */ 257 "00 00 00 0c 00 00 40 01 00 00 00 0a 00", 258 /* ciphertext */ 259 "61 03 94 70 1f 8d 01 7f 7c 12 92 48 89", 260 /* tag */ 261 "6b 71 bf e2 52 36 ef d7 cd c6 70 66 90 63 15 b2" 262 }, 263 264 /* Chacha20 test cases from the libcrypto aeadtests.txt */ 265 { 266 /* key + salt */ 267 "42 90 bc b1 54 17 35 31 f3 14 af 57 f3 be 3b 50 " 268 "06 da 37 1e ce 27 2a fa 1b 5d bd d1 10 0a 10 07 " 269 "00 00 00 00", 270 /* iv */ 271 "cd 7c f6 7b e3 9c 79 4a", 272 /* aad */ 273 NULL, 274 /* plaintext */ 275 "86 d0 99 74 84 0b de d2 a5 ca", 276 /* ciphertext */ 277 "e3 e4 46 f7 ed e9 a1 9b 62 a4", 278 /* tag */ 279 NULL 280 } 281 }; 282 283 static void 284 dochacha(unsigned char *key, size_t klen, unsigned char *iv, 285 size_t ivlen, unsigned char *plain, size_t plen) 286 { 287 struct chacha20_ctx ctx; 288 uint8_t blk[CHACHA20_BLOCK_LEN]; 289 int i; 290 291 memset(&ctx, 0, sizeof ctx); 292 293 if (chacha20_setkey(&ctx, key, CHACHA20_KEYSIZE + CHACHA20_SALT)) 294 errx(1, "chacha20_setkey"); 295 chacha20_reinit((caddr_t)&ctx, iv); 296 297 while (plen >= CHACHA20_BLOCK_LEN) { 298 chacha20_crypt((caddr_t)&ctx, plain); 299 plain += CHACHA20_BLOCK_LEN; 300 plen -= CHACHA20_BLOCK_LEN; 301 } 302 if (plen > 0) { 303 for (i = 0; i < plen; i++) 304 blk[i] = plain[i]; 305 for (; i < CHACHA20_BLOCK_LEN; i++) 306 blk[i] = 0; 307 chacha20_crypt((caddr_t)&ctx, blk); 308 memcpy(plain, blk, plen); 309 } 310 } 311 312 static void 313 dopoly(const unsigned char *key, size_t klen, 314 const unsigned char *iv, size_t ivlen, 315 const unsigned char *aad, size_t aadlen, 316 const unsigned char *in, unsigned char *out, size_t len) 317 { 318 CHACHA20_POLY1305_CTX ctx; 319 uint8_t blk[CHACHA20_BLOCK_LEN]; 320 uint32_t *p; 321 int i; 322 323 Chacha20_Poly1305_Init(&ctx); 324 325 Chacha20_Poly1305_Setkey(&ctx, key, klen); 326 327 Chacha20_Poly1305_Reinit(&ctx, iv, ivlen); 328 329 for (i = 0; i < aadlen; i += POLY1305_BLOCK_LEN) { 330 memset(blk, 0, POLY1305_BLOCK_LEN); 331 memcpy(blk, aad + i, MIN(aadlen - i, POLY1305_BLOCK_LEN)); 332 Chacha20_Poly1305_Update(&ctx, blk, POLY1305_BLOCK_LEN); 333 } 334 335 for (i = 0; i < len; i += CHACHA20_BLOCK_LEN) { 336 int dlen = MIN(len - i, CHACHA20_BLOCK_LEN); 337 Chacha20_Poly1305_Update(&ctx, in + i, dlen); 338 } 339 340 bzero(blk, sizeof blk); 341 p = (uint32_t *)blk; 342 *p = htole32(aadlen); 343 p = (uint32_t *)blk + 2; 344 *p = htole32(len); 345 Chacha20_Poly1305_Update(&ctx, blk, POLY1305_BLOCK_LEN); 346 347 Chacha20_Poly1305_Final(out, &ctx); 348 } 349 350 static int 351 match(unsigned char *a, unsigned char *b, size_t len) 352 { 353 int i; 354 355 if (memcmp(a, b, len) == 0) 356 return (1); 357 358 warnx("mismatch"); 359 360 for (i = 0; i < len; i++) 361 printf("%2.2x", a[i]); 362 printf("\n"); 363 for (i = 0; i < len; i++) 364 printf("%2.2x", b[i]); 365 printf("\n"); 366 367 return (0); 368 } 369 370 static int 371 run(int num) 372 { 373 int i, fail = 1, len, j, length[TST_NUM]; 374 u_long val; 375 char *ep, *from; 376 u_char *p, *data[TST_NUM], tag[POLY1305_TAGLEN]; 377 u_char *ciphertext; 378 379 for (i = 0; i < TST_NUM; i++) 380 data[i] = NULL; 381 for (i = 0; i < TST_NUM; i++) { 382 from = tests[num].data[i]; 383 if (debug) 384 printf("%s\n", from); 385 if (!from) { 386 length[i] = 0; 387 data[i] = NULL; 388 continue; 389 } 390 len = strlen(from); 391 if ((p = malloc(len)) == NULL) { 392 warn("malloc"); 393 goto done; 394 } 395 errno = 0; 396 for (j = 0; j < len; j++) { 397 val = strtoul(&from[j*3], &ep, 16); 398 p[j] = (u_char)val; 399 if (*ep == '\0' || errno) 400 break; 401 } 402 length[i] = j+1; 403 data[i] = p; 404 } 405 406 if (length[TST_PLAIN] != 0) { 407 dochacha(data[TST_KEY], length[TST_KEY], data[TST_IV], 408 length[TST_IV], data[TST_PLAIN], length[TST_PLAIN]); 409 fail = !match(data[TST_CIPHER], data[TST_PLAIN], 410 length[TST_PLAIN]); 411 printf("%s test vector %d (Chacha20)\n", 412 fail ? "FAILED" : "OK", num); 413 } 414 if (length[TST_AAD] != 0) { 415 dopoly(data[TST_KEY], length[TST_KEY], data[TST_IV], 416 length[TST_IV], data[TST_AAD], length[TST_AAD], 417 data[TST_CIPHER], tag, length[TST_CIPHER]); 418 fail = !match(data[TST_TAG], tag, POLY1305_TAGLEN); 419 printf("%s test vector %d (Poly1305)\n", 420 fail ? "FAILED" : "OK", num); 421 } 422 423 done: 424 for (i = 0; i < TST_NUM; i++) 425 free(data[i]); 426 return (fail); 427 } 428 429 int 430 main(void) 431 { 432 int i, fail = 0; 433 434 for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) 435 fail += run(i); 436 437 return (fail > 0 ? 1 : 0); 438 } 439