From ce58e85aa66849b81b2c575c41a130df6dbc985e Mon Sep 17 00:00:00 2001 From: makejian Date: Wed, 24 Jul 2024 21:46:07 +0800 Subject: [PATCH] testing/crypto: add ecdsa testing Signed-off-by: makejian --- testing/crypto/CMakeLists.txt | 14 ++ testing/crypto/Kconfig | 4 + testing/crypto/Makefile | 5 + testing/crypto/ecdsa.c | 326 ++++++++++++++++++++++++++++++++++ 4 files changed, 349 insertions(+) create mode 100644 testing/crypto/ecdsa.c diff --git a/testing/crypto/CMakeLists.txt b/testing/crypto/CMakeLists.txt index a1c6c776f..06c4f4d7f 100644 --- a/testing/crypto/CMakeLists.txt +++ b/testing/crypto/CMakeLists.txt @@ -131,4 +131,18 @@ if(CONFIG_TESTING_CRYPTO) aescmac.c) endif() + if(CONFIG_TESTING_CRYPTO_ECDSA) + nuttx_add_application( + NAME + ecdsa + PRIORITY + ${CONFIG_TESTING_CRYPTO_PRIORITY} + STACKSIZE + ${CONFIG_TESTING_CRYPTO_STACKSIZE} + MODULE + ${CONFIG_TESTING_CRYPTO} + SRCS + ecdsa.c) + endif() + endif() diff --git a/testing/crypto/Kconfig b/testing/crypto/Kconfig index 485f7f15f..4e322994a 100644 --- a/testing/crypto/Kconfig +++ b/testing/crypto/Kconfig @@ -38,6 +38,10 @@ config TESTING_CRYPTO_AES_CMAC bool "aes-cmac crypto test" default n +config TESTING_CRYPTO_ECDSA + bool "ecdsa crypto test" + default n + config TESTING_CRYPTO_PRIORITY int "crypto test task priority" default 100 diff --git a/testing/crypto/Makefile b/testing/crypto/Makefile index d76800371..3169efb5f 100644 --- a/testing/crypto/Makefile +++ b/testing/crypto/Makefile @@ -61,6 +61,11 @@ PROGNAME += aescmac MAINSRC += aescmac.c endif +ifeq ($(CONFIG_TESTING_CRYPTO_ECDSA),y) +PROGNAME += ecdsa +MAINSRC += ecdsa.c +endif + PRIORITY = $(CONFIG_TESTING_CRYPTO_PRIORITY) STACKSIZE = $(CONFIG_TESTING_CRYPTO_STACKSIZE) MODULE = $(CONFIG_TESTING_CRYPTO) diff --git a/testing/crypto/ecdsa.c b/testing/crypto/ecdsa.c new file mode 100644 index 000000000..6a62c247a --- /dev/null +++ b/testing/crypto/ecdsa.c @@ -0,0 +1,326 @@ +/**************************************************************************** + * apps/testing/crypto/ecdsa.c + * + * 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 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SECP256R1_KEYLEN 32 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static unsigned char sha256_message[32] = +{ + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad +}; + +/**************************************************************************** + * 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) +{ + 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 = 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[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) + { + perror("CIOCKEY"); + goto err; + } + + close(cryptodev_fd); + close(fd); + return cryptk.crk_status; + +err: + if (cryptodev_fd != -1) + { + close(cryptodev_fd); + } + + if (fd != -1) + { + close(fd); + } + + return -1; +} + +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, + 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[5].crp_p = (caddr_t)buf; + cryptk.crk_param[5].crp_nbits = buflen * 8; + + if (ioctl(cryptodev_fd, CIOCKEY, &cryptk) == -1) + { + perror("CIOCKEY"); + goto err; + } + + close(cryptodev_fd); + close(fd); + return cryptk.crk_status; + +err: + if (cryptodev_fd != -1) + { + close(cryptodev_fd); + } + + if (fd != -1) + { + close(fd); + } + + return -1; +} + +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) +{ + 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) + { + perror("CIOCKEY"); + goto err; + } + + close(cryptodev_fd); + close(fd); + return cryptk.crk_status; + +err: + if (cryptodev_fd != -1) + { + close(cryptodev_fd); + } + + if (fd != -1) + { + close(fd); + } + + return -1; +} + +/* Test curve SECP256R1 */ + +static int test_p256 (void) +{ + 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); + 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); + 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); + if (ret != 0) + { + printf("p256 verify failed\n"); + } + +free: + if (x) + { + free(x); + } + + if (y) + { + free(y); + } + + if (z) + { + free(z); + } + + if (d) + { + free(d); + } + + if (r) + { + free(r); + } + + if (s) + { + free(s); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(void) +{ + if (test_p256() == 0) + { + printf("p256 test success\n"); + } + + return 0; +}