| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 | /* * 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 hwcrypto_bignum_dev_is_init(void){    struct rt_hwcrypto_device *dev;    if (bignum_default)    {        return RT_EOK;    }    dev = rt_hwcrypto_dev_default();    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           Init bignum obj *  * @param n         bignum obj */void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n){    if(n == RT_NULL)        return;    n->sign = 1;    n->total = 0;    n->p = RT_NULL;}/** * @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);        n->sign = 0;        n->total = 0;        n->p = RT_NULL;    }}/** * @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           Export n into unsigned binary data, big endian *  * @param n         bignum obj * @param buf       Buffer for the binary number * @param len       Length of the buffer *  * @return          export bin length */int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len){    int cp_len, i, j;    if (n == RT_NULL || buf == RT_NULL)    {        return 0;    }    rt_memset(buf, 0, len);    cp_len = n->total > len ? len : n->total;    for(i = cp_len, j = 0; i > 0; i--, j++)    {        buf[i - 1] = n->p[j];    }    return cp_len;}/** * @brief           Import n from unsigned binary data, big endian *  * @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_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len){    int cp_len, i, j;    void *temp_p;    if (n == RT_NULL || buf == RT_NULL)    {        return 0;    }    if (n->total < len)    {        temp_p = rt_malloc(len);        if (temp_p == RT_NULL)        {            return 0;        }        rt_memset(temp_p, 0, len);        rt_free(n->p);        n->p = temp_p;        n->total = len;    }    cp_len = n->total > len ? len : n->total;    for(i = cp_len, j = 0; i > 0; i--, j++)    {        n->p[j] = buf[i - 1];    }    return cp_len;}/** * @brief           x = a + b *  * @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 *x,                                const struct hw_bignum_mpi *a,                                const struct hw_bignum_mpi *b){    struct hwcrypto_bignum *bignum_ctx;    if (hwcrypto_bignum_dev_is_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, x, a, b);    }    return -RT_ERROR;}/** * @brief           x = a - b *  * @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 *x,                                const struct hw_bignum_mpi *a,                                const struct hw_bignum_mpi *b){    struct hwcrypto_bignum *bignum_ctx;    if (hwcrypto_bignum_dev_is_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, x, a, b);    }    return -RT_ERROR;}/** * @brief           x = a * b *  * @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 *x,                                const struct hw_bignum_mpi *a,                                const struct hw_bignum_mpi *b){    struct hwcrypto_bignum *bignum_ctx;    if (hwcrypto_bignum_dev_is_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, x, a, b);    }    return -RT_ERROR;}/** * @brief           x = a * b (mod c) *  * @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 *x,                                   const struct hw_bignum_mpi *a,                                   const struct hw_bignum_mpi *b,                                   const struct hw_bignum_mpi *c){    struct hwcrypto_bignum *bignum_ctx;    if (hwcrypto_bignum_dev_is_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, x, a, b, c);    }    return -RT_ERROR;}/** * @brief           x = a ^ b (mod c) *  * @param a         bignum obj * @param b         bignum obj * @param c         bignum obj *  * @return          RT_EOK on success. */rt_err_t rt_hwcrypto_bignum_exptmod(struct hw_bignum_mpi *x,                                    const struct hw_bignum_mpi *a,                                    const struct hw_bignum_mpi *b,                                    const struct hw_bignum_mpi *c){    struct hwcrypto_bignum *bignum_ctx;    if (hwcrypto_bignum_dev_is_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, x, a, b, c);    }    return -RT_ERROR;}
 |