123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- /*
- * Copyright (c) 2006-2019, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-04-25 tyx the first version
- */
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <hw_bignum.h>
- static struct rt_hwcrypto_ctx *bignum_default;
- rt_inline rt_err_t rt_hwcrypto_bignum_init(void)
- {
- struct rt_hwcrypto_device *dev;
- if (bignum_default)
- {
- return RT_EOK;
- }
- dev = rt_hwcrypto_dev_dufault();
- if (dev == RT_NULL)
- {
- return -RT_ERROR;
- }
- return rt_hwcrypto_bignum_default(dev);
- }
- /**
- * @brief Setting bignum default devices
- *
- * @return RT_EOK on success.
- */
- rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device)
- {
- if (bignum_default)
- {
- rt_hwcrypto_ctx_destroy(bignum_default);
- bignum_default = RT_NULL;
- }
- if (device == RT_NULL)
- {
- return RT_EOK;
- }
- bignum_default = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_BIGNUM, sizeof(struct hwcrypto_bignum));
- if (bignum_default == RT_NULL)
- {
- return -RT_ERROR;
- }
- return RT_EOK;
- }
- /**
- * @brief Allocate memory for bignum
- *
- * @return Pointer to allocated bignum obj
- */
- struct hw_bignum_mpi *rt_hwcrypto_bignum_alloc(void)
- {
- struct hw_bignum_mpi *n;
- n = rt_malloc(sizeof(struct hw_bignum_mpi));
- if (n)
- {
- rt_memset(n, 0, sizeof(struct hw_bignum_mpi));
- }
- return n;
- }
- /**
- * @brief free a bignum obj
- *
- * @param Pointer to bignum obj
- */
- void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n)
- {
- if (n)
- {
- rt_free(n->p);
- rt_free(n);
- }
- }
- /**
- * @brief Get length of bignum as an unsigned binary buffer
- *
- * @param n bignum obj
- *
- * @return binary buffer Length
- */
- int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n)
- {
- int tmp_len, total;
- if (n == RT_NULL || n->p == RT_NULL)
- {
- return 0;
- }
- tmp_len = 0;
- total = n->total;
- while ((total > 0) && (n->p[total - 1] == 0))
- {
- tmp_len++;
- total--;
- }
- return n->total - tmp_len;
- }
- /**
- * @brief Get length of bignum as an unsigned binary buffer
- *
- * @param n bignum obj
- * @param buf Buffer for the binary number
- * @param len Length of the buffer
- *
- * @return binary buffer Length
- */
- int rt_hwcrypto_bignum_get_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
- {
- int cp_len;
- if (n == RT_NULL || n->p == RT_NULL || buf == RT_NULL)
- {
- return 0;
- }
- cp_len = n->total > len ? len : n->total;
- rt_memcpy(n->p, buf, cp_len);
- return cp_len;
- }
- /**
- * @brief Set binary buffer to unsigned bignum
- *
- * @param n bignum obj
- * @param buf Buffer for the binary number
- * @param len Length of the buffer
- *
- * @return RT_EOK on success.
- */
- rt_err_t rt_hwcrypto_bignum_set_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
- {
- void *temp_p;
- if (n == RT_NULL)
- {
- return -RT_EINVAL;
- }
- if (n->p && n->total >= len)
- {
- rt_memcpy(n->p, buf, len);
- return RT_EOK;
- }
- temp_p = rt_malloc(len);
- if (temp_p == RT_NULL)
- {
- return -RT_ENOMEM;
- }
- if (n->p)
- {
- rt_free(n->p);
- n->p = temp_p;
- n->total = 0;
- }
- rt_memcpy(n->p, buf, len);
- n->total = len;
- return RT_EOK;
- }
- /**
- * @brief Unsigned comparison
- *
- * @param a bignum obj
- * @param b bignum obj
- *
- * @return 0 is equal
- */
- int rt_hwcrypto_bignum_cmp(const struct hw_bignum_mpi *a,
- const struct hw_bignum_mpi *b)
- {
- int a_len, b_len;
- if (a == RT_NULL || a->p == RT_NULL
- || b == RT_NULL || b->p == RT_NULL)
- {
- return -1;
- }
- a_len = rt_hwcrypto_bignum_get_len(a);
- b_len = rt_hwcrypto_bignum_get_len(b);
- if (a_len != b_len)
- {
- return a_len - b_len;
- }
- return rt_memcmp(a->p, b->p, a_len);
- }
- /**
- * @brief Compare bignum to standard Unsigned integer
- *
- * @param a bignum obj
- * @param b Unsigned integer
- *
- * @return 0 is equal
- */
- int rt_hwcrypto_bignum_cmp_d(const struct hw_bignum_mpi *a, unsigned long b)
- {
- struct hw_bignum_mpi tmp_b;
- b = b <= 0 ? -b : b;
- tmp_b.total = sizeof(unsigned long);
- tmp_b.p = &b;
- return rt_hwcrypto_bignum_cmp(a, &tmp_b);
- }
- /**
- * @brief a = b + c
- *
- * @param a bignum obj
- * @param b bignum obj
- * @param c bignum obj
- *
- * @return RT_EOK on success.
- */
- rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *a,
- const struct hw_bignum_mpi *b,
- const struct hw_bignum_mpi *c)
- {
- struct hwcrypto_bignum *bignum_ctx;
- if (rt_hwcrypto_bignum_init() != RT_EOK)
- {
- return -RT_ERROR;
- }
- bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
- if (bignum_ctx->ops->add)
- {
- return bignum_ctx->ops->add(bignum_ctx, a, b, c);
- }
- return -RT_ERROR;
- }
- /**
- * @brief a = b - c
- *
- * @param a bignum obj
- * @param b bignum obj
- * @param c bignum obj
- *
- * @return RT_EOK on success.
- */
- rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *a,
- const struct hw_bignum_mpi *b,
- const struct hw_bignum_mpi *c)
- {
- struct hwcrypto_bignum *bignum_ctx;
- if (rt_hwcrypto_bignum_init() != RT_EOK)
- {
- return -RT_ERROR;
- }
- bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
- if (bignum_ctx->ops->sub)
- {
- return bignum_ctx->ops->sub(bignum_ctx, a, b, c);
- }
- return -RT_ERROR;
- }
- /**
- * @brief a = b * c
- *
- * @param a bignum obj
- * @param b bignum obj
- * @param c bignum obj
- *
- * @return RT_EOK on success.
- */
- rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *a,
- const struct hw_bignum_mpi *b,
- const struct hw_bignum_mpi *c)
- {
- struct hwcrypto_bignum *bignum_ctx;
- if (rt_hwcrypto_bignum_init() != RT_EOK)
- {
- return -RT_ERROR;
- }
- bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
- if (bignum_ctx->ops->mul)
- {
- return bignum_ctx->ops->mul(bignum_ctx, a, b, c);
- }
- return -RT_ERROR;
- }
- /**
- * @brief a = b * c (mod d)
- *
- * @param a bignum obj
- * @param b bignum obj
- * @param c bignum obj
- *
- * @return RT_EOK on success.
- */
- rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *a,
- const struct hw_bignum_mpi *b,
- const struct hw_bignum_mpi *c,
- const struct hw_bignum_mpi *d)
- {
- struct hwcrypto_bignum *bignum_ctx;
- if (rt_hwcrypto_bignum_init() != RT_EOK)
- {
- return -RT_ERROR;
- }
- bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
- if (bignum_ctx->ops->mulmod)
- {
- return bignum_ctx->ops->mulmod(bignum_ctx, a, b, c, d);
- }
- return -RT_ERROR;
- }
- /**
- * @brief a = b ^ c (mod d)
- *
- * @param a bignum obj
- * @param b bignum obj
- * @param c bignum obj
- *
- * @return RT_EOK on success.
- */
- rt_err_t bignum_exptmod(struct hw_bignum_mpi *a,
- const struct hw_bignum_mpi *b,
- const struct hw_bignum_mpi *c,
- const struct hw_bignum_mpi *d)
- {
- struct hwcrypto_bignum *bignum_ctx;
- if (rt_hwcrypto_bignum_init() != RT_EOK)
- {
- return -RT_ERROR;
- }
- bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
- if (bignum_ctx->ops->exptmod)
- {
- return bignum_ctx->ops->exptmod(bignum_ctx, a, b, c, d);
- }
- return -RT_ERROR;
- }
|