1/* $OpenBSD: aesctr.c,v 1.4 2021/12/13 16:56:49 deraadt Exp $ */ 2 3/* 4 * Copyright (c) 2005 Markus Friedl <markus@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20#include <crypto/aes.h> 21#include <err.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25#include <unistd.h> 26#include <limits.h> 27#include <errno.h> 28 29int debug = 0; 30 31enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM }; 32 33/* Test vectors from RFC 3686 */ 34struct { 35 char *data[TST_NUM]; 36} tests[] = { 37 /* 128 bit key */ 38 { 39 "AE 68 52 F8 12 10 67 CC 4B F7 A5 76 55 77 F3 9E " 40 "00 00 00 30", 41 "00 00 00 00 00 00 00 00", 42 "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67", 43 "E4 09 5D 4F B7 A7 B3 79 2D 61 75 A3 26 13 11 B8" 44 }, 45 { 46 "7E 24 06 78 17 FA E0 D7 43 D6 CE 1F 32 53 91 63 " 47 "00 6C B6 DB", 48 "C0 54 3B 59 DA 48 D9 0B", 49 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " 50 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F", 51 "51 04 A1 06 16 8A 72 D9 79 0D 41 EE 8E DA D3 88 " 52 "EB 2E 1E FC 46 DA 57 C8 FC E6 30 DF 91 41 BE 28" 53 }, 54 { 55 "76 91 BE 03 5E 50 20 A8 AC 6E 61 85 29 F9 A0 DC " 56 "00 E0 01 7B", 57 "27 77 7F 3F 4A 17 86 F0", 58 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " 59 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" 60 /*"20 21 22 23"*/, 61 "C1 CF 48 A8 9F 2F FD D9 CF 46 52 E9 EF DB 72 D7 " 62 "45 40 A4 2B DE 6D 78 36 D5 9A 5C EA AE F3 10 53" 63 /*"25 B2 07 2F"*/ 64 }, 65 /* 192 bit key */ 66 { 67 "16 AF 5B 14 5F C9 F5 79 C1 75 F9 3E 3B FB 0E ED " 68 "86 3D 06 CC FD B7 85 15 " 69 "00 00 00 48", 70 "36 73 3C 14 7D 6D 93 CB", 71 "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67", 72 "4B 55 38 4F E2 59 C9 C8 4E 79 35 A0 03 CB E9 28", 73 }, 74 { 75 "7C 5C B2 40 1B 3D C3 3C 19 E7 34 08 19 E0 F6 9C " 76 "67 8C 3D B8 E6 F6 A9 1A " 77 "00 96 B0 3B", 78 "02 0C 6E AD C2 CB 50 0D", 79 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " 80 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F", 81 "45 32 43 FC 60 9B 23 32 7E DF AA FA 71 31 CD 9F " 82 "84 90 70 1C 5A D4 A7 9C FC 1F E0 FF 42 F4 FB 00", 83 }, 84 { 85 "02 BF 39 1E E8 EC B1 59 B9 59 61 7B 09 65 27 9B " 86 "F5 9B 60 A7 86 D3 E0 FE " 87 "00 07 BD FD", 88 "5C BD 60 27 8D CC 09 12", 89 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " 90 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" 91 /*"20 21 22 23"*/, 92 "96 89 3F C5 5E 5C 72 2F 54 0B 7D D1 DD F7 E7 58 " 93 "D2 88 BC 95 C6 91 65 88 45 36 C8 11 66 2F 21 88" 94 /*"AB EE 09 35"*/, 95 }, 96 /* 256 bit key */ 97 { 98 "77 6B EF F2 85 1D B0 6F 4C 8A 05 42 C8 69 6F 6C " 99 "6A 81 AF 1E EC 96 B4 D3 7F C1 D6 89 E6 C1 C1 04 " 100 "00 00 00 60", 101 "DB 56 72 C9 7A A8 F0 B2", 102 "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67", 103 "14 5A D0 1D BF 82 4E C7 56 08 63 DC 71 E3 E0 C0" 104 }, 105 { 106 "F6 D6 6D 6B D5 2D 59 BB 07 96 36 58 79 EF F8 86 " 107 "C6 6D D5 1A 5B 6A 99 74 4B 50 59 0C 87 A2 38 84 " 108 "00 FA AC 24", 109 "C1 58 5E F1 5A 43 D8 75", 110 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " 111 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F", 112 "F0 5E 23 1B 38 94 61 2C 49 EE 00 0B 80 4E B2 A9 " 113 "B8 30 6B 50 8F 83 9D 6A 55 30 83 1D 93 44 AF 1C", 114 }, 115 { 116 "FF 7A 61 7C E6 91 48 E4 F1 72 6E 2F 43 58 1D E2 " 117 "AA 62 D9 F8 05 53 2E DF F1 EE D6 87 FB 54 15 3D " 118 "00 1C C5 B7", 119 "51 A5 1D 70 A1 C1 11 48", 120 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " 121 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" 122 /*"20 21 22 23"*/, 123 "EB 6C 52 82 1D 0B BB F7 CE 75 94 46 2A CA 4F AA " 124 "B4 07 DF 86 65 69 FD 07 F4 8C C0 B5 83 D6 07 1F" 125 /*"1E C0 E6 B8"*/, 126 }, 127}; 128 129/* Stubs */ 130 131u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **); 132 133u_int32_t 134deflate_global(u_int8_t *data, u_int32_t size, int comp, u_int8_t **out) 135{ 136 return 0; 137} 138 139void explicit_bzero(void *, size_t); 140 141void 142explicit_bzero(void *b, size_t len) 143{ 144 bzero(b, len); 145} 146 147/* Definitions from /sys/crypto/xform.c */ 148 149#define AESCTR_NONCESIZE 4 150#define AESCTR_IVSIZE 8 151#define AESCTR_BLOCKSIZE 16 152 153struct aes_ctr_ctx { 154 AES_CTX ac_key; 155 u_int8_t ac_block[AESCTR_BLOCKSIZE]; 156}; 157 158int aes_ctr_setkey(void *, u_int8_t *, int); 159void aes_ctr_encrypt(caddr_t, u_int8_t *); 160void aes_ctr_decrypt(caddr_t, u_int8_t *); 161void aes_ctr_reinit(caddr_t, u_int8_t *); 162 163static int 164docrypt(const unsigned char *key, size_t klen, const unsigned char *iv, 165 const unsigned char *in, unsigned char *out, size_t len, int encrypt) 166{ 167 u_int8_t block[AESCTR_BLOCKSIZE]; 168 struct aes_ctr_ctx ctx; 169 int error = 0; 170 size_t i; 171 172 error = aes_ctr_setkey(&ctx, (u_int8_t *)key, klen); 173 if (error) 174 return -1; 175 aes_ctr_reinit((caddr_t)&ctx, (u_int8_t *)iv); 176 for (i = 0; i < len / AESCTR_BLOCKSIZE; i++) { 177 bcopy(in, block, AESCTR_BLOCKSIZE); 178 in += AESCTR_BLOCKSIZE; 179 aes_ctr_crypt(&ctx, block); 180 bcopy(block, out, AESCTR_BLOCKSIZE); 181 out += AESCTR_BLOCKSIZE; 182 } 183 return 0; 184} 185 186static int 187match(unsigned char *a, unsigned char *b, size_t len) 188{ 189 int i; 190 191 if (memcmp(a, b, len) == 0) 192 return (1); 193 194 warnx("ciphertext mismatch"); 195 196 for (i = 0; i < len; i++) 197 printf("%2.2x", a[i]); 198 printf("\n"); 199 for (i = 0; i < len; i++) 200 printf("%2.2x", b[i]); 201 printf("\n"); 202 203 return (0); 204} 205 206static int 207run(int num) 208{ 209 int i, fail = 1, len, j, length[TST_NUM]; 210 u_long val; 211 char *ep, *from; 212 u_char *p, *data[TST_NUM]; 213 214 for (i = 0; i < TST_NUM; i++) 215 data[i] = NULL; 216 for (i = 0; i < TST_NUM; i++) { 217 from = tests[num].data[i]; 218 if (debug) 219 printf("%s\n", from); 220 len = strlen(from); 221 if ((p = malloc(len)) == 0) { 222 warn("malloc"); 223 goto done; 224 } 225 errno = 0; 226 for (j = 0; j < len; j++) { 227 val = strtoul(&from[j*3], &ep, 16); 228 p[j] = (u_char)val; 229 if (*ep == '\0' || errno) 230 break; 231 } 232 length[i] = j+1; 233 data[i] = p; 234 } 235 len = length[TST_PLAIN]; 236 if ((p = malloc(len)) == 0) { 237 warn("malloc"); 238 return (1); 239 } 240 if (docrypt(data[TST_KEY], length[TST_KEY], 241 data[TST_IV], data[TST_PLAIN], p, 242 length[TST_PLAIN], 0) < 0) { 243 warnx("encryption failed"); 244 goto done; 245 } 246 fail = !match(data[TST_CIPHER], p, len); 247 printf("%s test vector %d\n", fail ? "FAILED" : "OK", num); 248done: 249 for (i = 0; i < TST_NUM; i++) 250 free(data[i]); 251 return (fail); 252} 253 254int 255main(int argc, char **argv) 256{ 257 int fail = 0, i; 258 259 for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) 260 fail += run(i); 261 exit((fail > 0) ? 1 : 0); 262} 263