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;