1 /* $OpenBSD: aesctr.c,v 1.2 2014/08/15 14:39:04 mikeb 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/param.h> 20 #include <crypto/rijndael.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 29 int debug = 0; 30 31 enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM }; 32 33 /* Test vectors from RFC 3686 */ 34 struct { 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 131 u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **); 132 133 u_int32_t 134 deflate_global(u_int8_t *data, u_int32_t size, int comp, u_int8_t **out) 135 { 136 return 0; 137 } 138 139 void explicit_bzero(void *, size_t); 140 141 void 142 explicit_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 153 struct aes_ctr_ctx { 154 u_int32_t ac_ek[4*(AES_MAXROUNDS + 1)]; 155 u_int8_t ac_block[AESCTR_BLOCKSIZE]; 156 int ac_nr; 157 }; 158 159 int aes_ctr_setkey(void *, u_int8_t *, int); 160 void aes_ctr_encrypt(caddr_t, u_int8_t *); 161 void aes_ctr_decrypt(caddr_t, u_int8_t *); 162 void aes_ctr_reinit(caddr_t, u_int8_t *); 163 164 static int 165 docrypt(const unsigned char *key, size_t klen, const unsigned char *iv, 166 const unsigned char *in, unsigned char *out, size_t len, int encrypt) 167 { 168 u_int8_t block[AESCTR_BLOCKSIZE]; 169 struct aes_ctr_ctx ctx; 170 int error = 0; 171 size_t i; 172 173 error = aes_ctr_setkey(&ctx, (u_int8_t *)key, klen); 174 if (error) 175 return -1; 176 aes_ctr_reinit((caddr_t)&ctx, (u_int8_t *)iv); 177 for (i = 0; i < len / AESCTR_BLOCKSIZE; i++) { 178 bcopy(in, block, AESCTR_BLOCKSIZE); 179 in += AESCTR_BLOCKSIZE; 180 aes_ctr_crypt(&ctx, block); 181 bcopy(block, out, AESCTR_BLOCKSIZE); 182 out += AESCTR_BLOCKSIZE; 183 } 184 return 0; 185 186 } 187 188 static int 189 match(unsigned char *a, unsigned char *b, size_t len) 190 { 191 int i; 192 193 if (memcmp(a, b, len) == 0) 194 return (1); 195 196 warnx("ciphertext mismatch"); 197 198 for (i = 0; i < len; i++) 199 printf("%2.2x", a[i]); 200 printf("\n"); 201 for (i = 0; i < len; i++) 202 printf("%2.2x", b[i]); 203 printf("\n"); 204 205 return (0); 206 } 207 208 static int 209 run(int num) 210 { 211 int i, fail = 1, len, j, length[TST_NUM]; 212 u_long val; 213 char *ep, *from; 214 u_char *p, *data[TST_NUM]; 215 216 for (i = 0; i < TST_NUM; i++) 217 data[i] = NULL; 218 for (i = 0; i < TST_NUM; i++) { 219 from = tests[num].data[i]; 220 if (debug) 221 printf("%s\n", from); 222 len = strlen(from); 223 if ((p = malloc(len)) == 0) { 224 warn("malloc"); 225 goto done; 226 } 227 errno = 0; 228 for (j = 0; j < len; j++) { 229 val = strtoul(&from[j*3], &ep, 16); 230 p[j] = (u_char)val; 231 if (*ep == '\0' || errno) 232 break; 233 } 234 length[i] = j+1; 235 data[i] = p; 236 } 237 len = length[TST_PLAIN]; 238 if ((p = malloc(len)) == 0) { 239 warn("malloc"); 240 return (1); 241 } 242 if (docrypt(data[TST_KEY], length[TST_KEY], 243 data[TST_IV], data[TST_PLAIN], p, 244 length[TST_PLAIN], 0) < 0) { 245 warnx("crypt with /dev/crypto failed"); 246 goto done; 247 } 248 fail = !match(data[TST_CIPHER], p, len); 249 printf("%s test vector %d\n", fail ? "FAILED" : "OK", num); 250 done: 251 for (i = 0; i < TST_NUM; i++) 252 free(data[i]); 253 return (fail); 254 } 255 256 int 257 main(int argc, char **argv) 258 { 259 int fail = 0, i; 260 261 for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) 262 fail += run(i); 263 exit((fail > 0) ? 1 : 0); 264 } 265