nuttx-apps/testing/crypto/aesctr.c

361 lines
8.3 KiB
C
Raw Normal View History

/****************************************************************************
* apps/testing/crypto/aesctr.c
* $OpenBSD: aesctr.c,v 1.1 2005/05/25 05:47:53 markus Exp $
*
* Copyright (c) 2005 Markus Friedl <markus@openbsd.org>
*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <crypto/cryptodev.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
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]);
}
free(p);
return (fail);
}
/****************************************************************************
* Public Functions
****************************************************************************/
int main(int argc, FAR char **argv)
{
int fail = 0;
int i;
for (i = 0; i < nitems(tests); i++)
{
fail += run(i);
}
exit((fail > 0) ? 1 : 0);
}