/**************************************************************************** * apps/testing/crypto/aesctr.c * $OpenBSD: aesctr.c,v 1.1 2005/05/25 05:47:53 markus Exp $ * * Copyright (c) 2005 Markus Friedl * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include static int debug = 0; enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM }; /* Test vectors from RFC 3686 */ struct { FAR char *data[TST_NUM]; } static tests[] = { /* 128 bit key */ { { "ae 68 52 f8 12 10 67 cc 4b f7 a5 76 55 77 f3 9e " "00 00 00 30", "00 00 00 00 00 00 00 00", "53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67", "e4 09 5d 4f b7 a7 b3 79 2d 61 75 a3 26 13 11 b8" } }, { { "7e 24 06 78 17 fa e0 d7 43 d6 ce 1f 32 53 91 63 " "00 6c b6 db", "c0 54 3b 59 da 48 d9 0b", "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f", "51 04 a1 06 16 8a 72 d9 79 0d 41 ee 8e da d3 88 " "eb 2e 1e fc 46 da 57 c8 fc e6 30 df 91 41 be 28" } }, { { "76 91 be 03 5e 50 20 a8 ac 6e 61 85 29 f9 a0 dc " "00 e0 01 7b", "27 77 7f 3f 4a 17 86 f0", "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f" /* "20 21 22 23" */, "c1 cf 48 a8 9f 2f fd d9 cf 46 52 e9 ef db 72 d7 " "45 40 a4 2b de 6d 78 36 d5 9a 5c ea ae f3 10 53" /* "25 b2 07 2f" */ } }, /* 192 bit key */ { { "16 af 5b 14 5f c9 f5 79 c1 75 f9 3e 3b fb 0e ed " "86 3d 06 cc fd b7 85 15 " "00 00 00 48", "36 73 3c 14 7d 6d 93 cb", "53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67", "4b 55 38 4f e2 59 c9 c8 4e 79 35 a0 03 cb e9 28", } }, { { "7c 5c b2 40 1b 3d c3 3c 19 e7 34 08 19 e0 f6 9c " "67 8c 3d b8 e6 f6 a9 1a " "00 96 b0 3b", "02 0c 6e ad c2 cb 50 0d", "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f", "45 32 43 fc 60 9b 23 32 7e df aa fa 71 31 cd 9f " "84 90 70 1c 5a d4 a7 9c fc 1f e0 ff 42 f4 fb 00", } }, { { "02 bf 39 1e e8 ec b1 59 b9 59 61 7b 09 65 27 9b " "f5 9b 60 a7 86 d3 e0 fe " "00 07 bd fd", "5c bd 60 27 8d cc 09 12", "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f" /* "20 21 22 23" */, "96 89 3f c5 5e 5c 72 2f 54 0b 7d d1 dd f7 e7 58 " "d2 88 bc 95 c6 91 65 88 45 36 c8 11 66 2f 21 88" /* "ab ee 09 35" */, } }, /* 256 bit key */ { { "77 6b ef f2 85 1d b0 6f 4c 8a 05 42 c8 69 6f 6c " "6a 81 af 1e ec 96 b4 d3 7f c1 d6 89 e6 c1 c1 04 " "00 00 00 60", "db 56 72 c9 7a a8 f0 b2", "53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67", "14 5a d0 1d bf 82 4e c7 56 08 63 dc 71 e3 e0 c0" } }, { { "f6 d6 6d 6b d5 2d 59 bb 07 96 36 58 79 ef f8 86 " "c6 6d d5 1a 5b 6a 99 74 4b 50 59 0c 87 a2 38 84 " "00 fa ac 24", "c1 58 5e f1 5a 43 d8 75", "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f", "f0 5e 23 1b 38 94 61 2c 49 ee 00 0b 80 4e b2 a9 " "b8 30 6b 50 8f 83 9d 6a 55 30 83 1d 93 44 af 1c", } }, { { "ff 7a 61 7c e6 91 48 e4 f1 72 6e 2f 43 58 1d e2 " "aa 62 d9 f8 05 53 2e df f1 ee d6 87 fb 54 15 3d " "00 1c c5 b7", "51 a5 1d 70 a1 c1 11 48", "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f" /* "20 21 22 23" */, "eb 6c 52 82 1d 0b bb f7 ce 75 94 46 2a ca 4f aa " "b4 07 df 86 65 69 fd 07 f4 8c c0 b5 83 d6 07 1f" /* "1e c0 e6 b8" */, } }, }; static int syscrypt(FAR const unsigned char *key, size_t klen, FAR const unsigned char *iv, FAR const unsigned char *in, FAR unsigned char *out, size_t len, int encrypt) { struct session_op session; struct crypt_op cryp; int cryptodev_fd = -1; int fd = -1; if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { warn("/dev/crypto"); goto err; } if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) { warn("CRIOGET"); goto err; } memset(&session, 0, sizeof(session)); session.cipher = CRYPTO_AES_CTR; session.key = (caddr_t) key; session.keylen = klen; if (ioctl(cryptodev_fd, CIOCGSESSION, &session) == -1) { warn("CIOCGSESSION"); goto err; } memset(&cryp, 0, sizeof(cryp)); cryp.ses = session.ses; cryp.op = encrypt ? COP_ENCRYPT : COP_DECRYPT; cryp.flags = 0; cryp.len = len; cryp.src = (caddr_t) in; cryp.dst = (caddr_t) out; cryp.iv = (caddr_t) iv; cryp.mac = 0; if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { warn("CIOCCRYPT"); goto err; } if (ioctl(cryptodev_fd, CIOCFSESSION, &session.ses) == -1) { warn("CIOCFSESSION"); goto err; } close(cryptodev_fd); close(fd); return (0); err: if (cryptodev_fd != -1) { close(cryptodev_fd); } if (fd != -1) { close(fd); } return (-1); } static int match(FAR unsigned char *a, FAR unsigned char *b, size_t len) { int i; if (memcmp(a, b, len) == 0) { return (1); } warnx("ciphertext mismatch"); for (i = 0; i < len; i++) { printf("%2.2x", a[i]); } printf("\n"); for (i = 0; i < len; i++) { printf("%2.2x", b[i]); } printf("\n"); return (0); } static int run(int num) { int i; int fail = 1; int len; int j; int length[TST_NUM]; u_long val; FAR char *ep; FAR char *from; FAR u_char *p; FAR u_char *data[TST_NUM]; for (i = 0; i < TST_NUM; i++) { data[i] = NULL; } for (i = 0; i < TST_NUM; i++) { from = tests[num].data[i]; if (debug) { printf("%s\n", from); } len = strlen(from); if ((p = malloc(len)) == 0) { warn("malloc"); goto done; } errno = 0; for (j = 0; j < len; j++) { val = strtoul(&from[j * 3], &ep, 16); p[j] = (u_char)val; if (*ep == '\0' || errno) break; } length[i] = j + 1; data[i] = p; } len = length[TST_PLAIN]; if ((p = malloc(len)) == 0) { warn("malloc"); return (1); } if (syscrypt(data[TST_KEY], length[TST_KEY], data[TST_IV], data[TST_PLAIN], p, length[TST_PLAIN], 0) < 0) { warnx("crypt with /dev/crypto failed"); goto done; } fail = !match(data[TST_CIPHER], p, len); printf("%s test vector %d\n", fail ? "FAILED" : "OK", num); done: for (i = 0; i < TST_NUM; i++) { free(data[i]); } return (fail); } /**************************************************************************** * Public Functions ****************************************************************************/ int main(int argc, FAR char **argv) { int fail = 0; int i; for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) { fail += run(i); } exit((fail > 0) ? 1 : 0); }