From 8545512dd7fbab80eeff3a74631e3b62f6e3918d Mon Sep 17 00:00:00 2001 From: makejian Date: Wed, 28 Aug 2024 22:16:53 +0800 Subject: [PATCH] testing/crypto: add ECDSA P256 testing case for asynchronous call 1. Add asynchronous call test into ecdsa test case. 2. Add command line parameters to facilitate subsequent expansion. Now can test synchronous call through 'ecdsa -s SECP256R1' and test asynchronous call through 'ecdsa -a SECP256R1' Signed-off-by: makejian --- testing/crypto/ecdsa.c | 482 +++++++++++++++++++++++++++-------------- 1 file changed, 317 insertions(+), 165 deletions(-) diff --git a/testing/crypto/ecdsa.c b/testing/crypto/ecdsa.c index 6a62c247a5e..c0ef261a44b 100644 --- a/testing/crypto/ecdsa.c +++ b/testing/crypto/ecdsa.c @@ -19,6 +19,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -31,8 +32,47 @@ * Pre-processor Definitions ****************************************************************************/ +#define ECC_KEYLEN_MAX 64 #define SECP256R1_KEYLEN 32 +typedef enum +{ + SYNC = 0, + ASYNC, +} +crypto_mode_t; + +typedef struct ecdsa_data_s +{ + unsigned char x[ECC_KEYLEN_MAX]; + unsigned char y[ECC_KEYLEN_MAX]; + unsigned char z[ECC_KEYLEN_MAX]; + unsigned char d[ECC_KEYLEN_MAX]; + unsigned char r[ECC_KEYLEN_MAX]; + unsigned char s[ECC_KEYLEN_MAX]; + size_t xlen; + size_t ylen; + size_t zlen; + size_t dlen; + size_t rlen; + size_t slen; +} +ecdsa_data_t; + +typedef struct crypto_context_s +{ + int fd; + int cryptodev_fd; +} +crypto_context_t; + +typedef struct ecdsa_test_s +{ + const char *name; + int (*function)(int); +} +ecdsa_test_t; + /**************************************************************************** * Private Data ****************************************************************************/ @@ -49,277 +89,389 @@ static unsigned char sha256_message[32] = * Private Functions ****************************************************************************/ -static int ecdsa_sign(int op, FAR unsigned char *r, size_t rlen, - FAR unsigned char *s, size_t slen, - FAR unsigned char *d, size_t dlen, - FAR const unsigned char *buf, size_t buflen) +static void show_usage(FAR const char *progname, int exitcode) { - struct crypt_kop cryptk; - int cryptodev_fd = -1; - int fd = -1; + printf("Usage: %s -a/-s \n", progname); + printf(" [-s] selects synchronous mode.\n"); + printf(" [-a] selects asynchronous mode.\n"); + printf(" [curve] selects the support curve.\n" + " support: SECP256R1\n"); + exit(exitcode); +} + +static int ecdsa_data_init(FAR ecdsa_data_t *data, + size_t xlen, size_t ylen, size_t zlen, + size_t dlen, size_t rlen, size_t slen) +{ + memset(data, 0, sizeof(ecdsa_data_t)); + data->xlen = xlen; + data->ylen = ylen; + data->zlen = zlen; + data->dlen = dlen; + data->rlen = rlen; + data->slen = slen; + return 0; +} - if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) +static void crypto_free(FAR crypto_context_t *ctx) +{ + if (ctx->cryptodev_fd != 0) + { + close(ctx->cryptodev_fd); + ctx->cryptodev_fd = 0; + } + + if (ctx->fd != 0) { - perror("/dev/crypto"); - goto err; + close(ctx->fd); + ctx->fd = 0; } +} - if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) +static int crypto_init(FAR crypto_context_t *ctx) +{ + memset(ctx, 0, sizeof(crypto_context_t)); + if ((ctx->fd = open("/dev/crypto", O_RDWR, 0)) < 0) { perror("CRIOGET"); - goto err; + crypto_free(ctx); + return 1; } + if (ioctl(ctx->fd, CRIOGET, &ctx->cryptodev_fd) == -1) + { + perror("CRIOGET"); + crypto_free(ctx); + return 1; + } + + return 0; +} + +static int ecdsa_sign(int op, FAR struct pollfd *fds, + FAR crypto_context_t *ctx, FAR ecdsa_data_t *data, + FAR const unsigned char *buf, size_t buflen) +{ + struct crypt_kop cryptk; + memset(&cryptk, 0, sizeof(cryptk)); cryptk.crk_op = op; cryptk.crk_iparams = 2; cryptk.crk_oparams = 2; - cryptk.crk_param[0].crp_p = (caddr_t)d; - cryptk.crk_param[0].crp_nbits = dlen * 8; + cryptk.crk_param[0].crp_p = (caddr_t)data->d; + cryptk.crk_param[0].crp_nbits = data->dlen * 8; cryptk.crk_param[1].crp_p = (caddr_t)buf; cryptk.crk_param[1].crp_nbits = buflen * 8; - cryptk.crk_param[2].crp_p = (caddr_t)r; - cryptk.crk_param[2].crp_nbits = rlen * 8; - cryptk.crk_param[3].crp_p = (caddr_t)s; - cryptk.crk_param[3].crp_nbits = slen * 8; - - if (ioctl(cryptodev_fd, CIOCKEY, &cryptk) == -1) + cryptk.crk_param[2].crp_p = (caddr_t)data->r; + cryptk.crk_param[2].crp_nbits = data->rlen * 8; + cryptk.crk_param[3].crp_p = (caddr_t)data->s; + cryptk.crk_param[3].crp_nbits = data->slen * 8; + if (fds != NULL) { - perror("CIOCKEY"); - goto err; + cryptk.crk_flags |= CRYPTO_F_CBIMM; } - close(cryptodev_fd); - close(fd); - return cryptk.crk_status; - -err: - if (cryptodev_fd != -1) + if (ioctl(ctx->cryptodev_fd, CIOCKEY, &cryptk) == -1) { - close(cryptodev_fd); + perror("CIOCKEY"); + return -1; } - if (fd != -1) + if (fds != NULL) { - close(fd); + memset(fds, 0, sizeof(struct pollfd)); + fds->fd = ctx->cryptodev_fd; + fds->events = POLLIN; + + if (poll(fds, 1, -1) < 0) + { + perror("poll"); + return -1; + } + + if (fds->revents & POLLIN) + { + if (ioctl(ctx->cryptodev_fd, CIOCKEYRET, &cryptk) == -1) + { + perror("CIOCKEYRET"); + return -1; + } + } + else + { + perror("poll back"); + return -1; + } } - return -1; + return cryptk.crk_status; } -static int ecdsa_verify(int op, FAR const unsigned char *qx, size_t qxlen, - FAR const unsigned char *qy, size_t qylen, - FAR const unsigned char *qz, size_t qzlen, - FAR const unsigned char *r, size_t rlen, - FAR const unsigned char *s, size_t slen, +static int ecdsa_verify(int op, FAR struct pollfd *fds, + FAR crypto_context_t *ctx, FAR ecdsa_data_t *data, FAR const unsigned char *buf, size_t buflen) { struct crypt_kop cryptk; - int cryptodev_fd = -1; - int fd = -1; - - if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) - { - perror("/dev/crypto"); - goto err; - } - - if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) - { - perror("CRIOGET"); - goto err; - } memset(&cryptk, 0, sizeof(cryptk)); cryptk.crk_op = op; cryptk.crk_iparams = 6; cryptk.crk_oparams = 0; - cryptk.crk_param[0].crp_p = (caddr_t)qx; - cryptk.crk_param[0].crp_nbits = qxlen * 8; - cryptk.crk_param[1].crp_p = (caddr_t)qy; - cryptk.crk_param[1].crp_nbits = qylen * 8; - cryptk.crk_param[2].crp_p = (caddr_t)qz; - cryptk.crk_param[2].crp_nbits = qzlen * 8; - cryptk.crk_param[3].crp_p = (caddr_t)r; - cryptk.crk_param[3].crp_nbits = rlen * 8; - cryptk.crk_param[4].crp_p = (caddr_t)s; - cryptk.crk_param[4].crp_nbits = slen * 8; + cryptk.crk_param[0].crp_p = (caddr_t)data->x; + cryptk.crk_param[0].crp_nbits = data->xlen * 8; + cryptk.crk_param[1].crp_p = (caddr_t)data->y; + cryptk.crk_param[1].crp_nbits = data->ylen * 8; + cryptk.crk_param[2].crp_p = (caddr_t)data->z; + cryptk.crk_param[2].crp_nbits = data->zlen * 8; + cryptk.crk_param[3].crp_p = (caddr_t)data->r; + cryptk.crk_param[3].crp_nbits = data->rlen * 8; + cryptk.crk_param[4].crp_p = (caddr_t)data->s; + cryptk.crk_param[4].crp_nbits = data->slen * 8; cryptk.crk_param[5].crp_p = (caddr_t)buf; cryptk.crk_param[5].crp_nbits = buflen * 8; - - if (ioctl(cryptodev_fd, CIOCKEY, &cryptk) == -1) + if (fds != NULL) { - perror("CIOCKEY"); - goto err; + cryptk.crk_flags |= CRYPTO_F_CBIMM; } - close(cryptodev_fd); - close(fd); - return cryptk.crk_status; - -err: - if (cryptodev_fd != -1) + if (ioctl(ctx->cryptodev_fd, CIOCKEY, &cryptk) == -1) { - close(cryptodev_fd); + perror("CIOCKEY"); + return -1; } - if (fd != -1) + if (fds != NULL) { - close(fd); + memset(fds, 0, sizeof(struct pollfd)); + fds->fd = ctx->cryptodev_fd; + fds->events = POLLIN; + + if (poll(fds, 1, -1) < 0) + { + perror("poll"); + return -1; + } + + if (fds->revents & POLLIN) + { + if (ioctl(ctx->cryptodev_fd, CIOCKEYRET, &cryptk) == -1) + { + perror("CIOCKEYRET"); + return -1; + } + } + else + { + perror("poll back"); + return -1; + } } - return -1; + return cryptk.crk_status; } -static int ecdsa_genkey(int op, FAR const unsigned char *d, size_t dlen, - FAR const unsigned char *qx, size_t qxlen, - FAR const unsigned char *qy, size_t qylen, - FAR const unsigned char *qz, size_t qzlen) +static int ecdsa_genkey(int op, FAR struct pollfd *fds, + FAR crypto_context_t *ctx, FAR ecdsa_data_t *data) { struct crypt_kop cryptk; - int cryptodev_fd = -1; - int fd = -1; - - if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) - { - perror("/dev/crypto"); - goto err; - } - - if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) - { - perror("CRIOGET"); - goto err; - } memset(&cryptk, 0, sizeof(cryptk)); cryptk.crk_op = op; cryptk.crk_iparams = 0; cryptk.crk_oparams = 4; - cryptk.crk_param[0].crp_p = (caddr_t)d; - cryptk.crk_param[0].crp_nbits = dlen * 8; - cryptk.crk_param[1].crp_p = (caddr_t)qx; - cryptk.crk_param[1].crp_nbits = qxlen * 8; - cryptk.crk_param[2].crp_p = (caddr_t)qy; - cryptk.crk_param[2].crp_nbits = qylen * 8; - cryptk.crk_param[3].crp_p = (caddr_t)qz; - cryptk.crk_param[3].crp_nbits = qzlen * 8; - - if (ioctl(cryptodev_fd, CIOCKEY, &cryptk) == -1) + cryptk.crk_param[0].crp_p = (caddr_t)data->d; + cryptk.crk_param[0].crp_nbits = data->dlen * 8; + cryptk.crk_param[1].crp_p = (caddr_t)data->x; + cryptk.crk_param[1].crp_nbits = data->xlen * 8; + cryptk.crk_param[2].crp_p = (caddr_t)data->y; + cryptk.crk_param[2].crp_nbits = data->ylen * 8; + cryptk.crk_param[3].crp_p = (caddr_t)data->z; + cryptk.crk_param[3].crp_nbits = data->zlen * 8; + if (fds != NULL) { - perror("CIOCKEY"); - goto err; + cryptk.crk_flags |= CRYPTO_F_CBIMM; } - close(cryptodev_fd); - close(fd); - return cryptk.crk_status; - -err: - if (cryptodev_fd != -1) + if (ioctl(ctx->cryptodev_fd, CIOCKEY, &cryptk) == -1) { - close(cryptodev_fd); + perror("CIOCKEY"); + return -1; } - if (fd != -1) + if (fds != NULL) { - close(fd); + memset(fds, 0, sizeof(struct pollfd)); + fds->fd = ctx->cryptodev_fd; + fds->events = POLLIN; + + if (poll(fds, 1, -1) < 0) + { + perror("poll"); + return -1; + } + + if (fds->revents & POLLIN) + { + if (ioctl(ctx->cryptodev_fd, CIOCKEYRET, &cryptk) == -1) + { + perror("CIOCKEYRET"); + return -1; + } + } + else + { + perror("poll back"); + return -1; + } } - return -1; + return cryptk.crk_status; } /* Test curve SECP256R1 */ -static int test_p256 (void) +static int test_p256(int mode) { + crypto_context_t ctx; + ecdsa_data_t data; + struct pollfd fds; int ret = 0; int len = SECP256R1_KEYLEN; - unsigned char *x = (unsigned char *)malloc(len); - unsigned char *y = (unsigned char *)malloc(len); - unsigned char *z = (unsigned char *)malloc(len); - unsigned char *d = (unsigned char *)malloc(len); - unsigned char *r = (unsigned char *)malloc(len); - unsigned char *s = (unsigned char *)malloc(len); - - if (x == NULL || y == NULL || z == NULL || - d == NULL || r == NULL || s == NULL) - { - perror("Error no enough buffer"); - goto free; - } - memset(x, 0, len); - memset(y, 0, len); - memset(z, 0, len); - memset(d, 0, len); - - ret = ecdsa_genkey(CRK_ECDSA_SECP256R1_GENKEY, x, len, - y, len, z, len, d, len); + ret = crypto_init(&ctx); if (ret != 0) { - printf("p256 generate key failed\n"); goto free; } - ret = ecdsa_sign(CRK_ECDSA_SECP256R1_SIGN, r, len, s, len, - d, len, sha256_message, len); + ret = ecdsa_data_init(&data, len, len, len, len, len, len); if (ret != 0) { - printf("p256 sign failed\n"); goto free; } - ret = ecdsa_verify(CRK_ECDSA_SECP256R1_VERIFY, x, len, y, len, - z, len, r, len, s, len, sha256_message, len); + ret = ecdsa_genkey(CRK_ECDSA_SECP256R1_GENKEY, mode == SYNC ? NULL : &fds, + &ctx, &data); if (ret != 0) { - printf("p256 verify failed\n"); - } - -free: - if (x) - { - free(x); + printf("p256 generate key %s failed\n", + mode == SYNC ? "sync" : "async"); + goto free; } - - if (y) + else { - free(y); + printf("p256 generate key %s success\n", + mode == SYNC ? "sync" : "async"); } - if (z) + ret = ecdsa_sign(CRK_ECDSA_SECP256R1_SIGN, mode == SYNC ? NULL : &fds, + &ctx, &data, sha256_message, len); + if (ret != 0) { - free(z); + printf("p256 sign %s failed\n", mode == SYNC ? "sync" : "async"); + goto free; } - - if (d) + else { - free(d); + printf("p256 sign %s success\n", mode == SYNC ? "sync" : "async"); } - if (r) + ret = ecdsa_verify(CRK_ECDSA_SECP256R1_VERIFY, mode == SYNC ? NULL : &fds, + &ctx, &data, sha256_message, len); + if (ret != 0) { - free(r); + printf("p256 verify %s failed\n", mode == SYNC ? "sync" : "async"); + goto free; } - - if (s) + else { - free(s); + printf("p256 verify %s success\n", mode == SYNC ? "sync" : "async"); } +free: + crypto_free(&ctx); return ret; } +static const ecdsa_test_t g_ecdsa_test[] = +{ + { + "SECP256R1", test_p256, + }, + + /* end test case */ + + { + NULL, NULL, + }, +}; + /**************************************************************************** * Public Functions ****************************************************************************/ -int main(void) +int main(int argc, FAR char *argv[]) { - if (test_p256() == 0) + char **argp; + crypto_mode_t mode = SYNC; + const ecdsa_test_t *test; + + for (argp = argv + (argc >= 1 ? 1 : argc); *argp != NULL; ++argp) + { + if (strcmp(*argp, "-s") == 0) + { + mode = SYNC; + } + else if (strcmp(*argp, "-a") == 0) + { + mode = ASYNC; + } + else if (strcmp(*argp, "-h") == 0) + { + show_usage(argv[0], EXIT_FAILURE); + } + else + { + break; + } + } + + if (*argp != NULL) + { + for (; *argp != NULL; argp++) + { + for (test = g_ecdsa_test; test->name != NULL; test++) + { + if (strcmp(*argp, test->name) == 0) + { + if (test->function(mode) != 0) + { + printf("Test %s case failed\n\n", *argp); + } + else + { + printf("Test %s case success\n\n", *argp); + } + + break; + } + } + } + } + else { - printf("p256 test success\n"); + for (test = g_ecdsa_test; test->name != NULL; test++) + { + if (test->function(mode) != 0) + { + printf("Test %s case failed\n\n", test->name); + break; + } + else + { + printf("Test %s case success\n\n", test->name); + } + } } return 0;