2019-05-24 20:04:27 +08:00
|
|
|
/*
|
2021-03-08 18:19:04 +08:00
|
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
2019-05-24 20:04:27 +08:00
|
|
|
*
|
|
|
|
* 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;
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
rt_inline rt_err_t hwcrypto_bignum_dev_is_init(void)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
struct rt_hwcrypto_device *dev;
|
|
|
|
|
|
|
|
if (bignum_default)
|
|
|
|
{
|
|
|
|
return RT_EOK;
|
|
|
|
}
|
2019-07-15 13:45:32 +08:00
|
|
|
dev = rt_hwcrypto_dev_default();
|
2019-05-24 20:04:27 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief Init bignum obj
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-06-05 14:49:19 +08:00
|
|
|
* @param n bignum obj
|
2019-05-24 20:04:27 +08:00
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
if(n == RT_NULL)
|
|
|
|
return;
|
2019-05-24 20:04:27 +08:00
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
n->sign = 1;
|
|
|
|
n->total = 0;
|
|
|
|
n->p = RT_NULL;
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
2019-06-05 14:49:19 +08:00
|
|
|
n->sign = 0;
|
|
|
|
n->total = 0;
|
|
|
|
n->p = RT_NULL;
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get length of bignum as an unsigned binary buffer
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param n bignum obj
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-06-05 14:49:19 +08:00
|
|
|
* @return binary buffer length
|
2019-05-24 20:04:27 +08:00
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief Export n into unsigned binary data, big endian
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param n bignum obj
|
|
|
|
* @param buf Buffer for the binary number
|
|
|
|
* @param len Length of the buffer
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-06-05 14:49:19 +08:00
|
|
|
* @return export bin length
|
2019-05-24 20:04:27 +08:00
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
int cp_len, i, j;
|
2019-05-24 20:04:27 +08:00
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
if (n == RT_NULL || buf == RT_NULL)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2019-06-05 14:49:19 +08:00
|
|
|
rt_memset(buf, 0, len);
|
2019-05-24 20:04:27 +08:00
|
|
|
cp_len = n->total > len ? len : n->total;
|
2019-06-05 14:49:19 +08:00
|
|
|
for(i = cp_len, j = 0; i > 0; i--, j++)
|
|
|
|
{
|
|
|
|
buf[i - 1] = n->p[j];
|
|
|
|
}
|
|
|
|
|
2019-05-24 20:04:27 +08:00
|
|
|
return cp_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief Import n from unsigned binary data, big endian
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param n bignum obj
|
|
|
|
* @param buf Buffer for the binary number
|
|
|
|
* @param len Length of the buffer
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @return RT_EOK on success.
|
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
rt_err_t rt_hwcrypto_bignum_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
int cp_len, i, j;
|
2019-05-24 20:04:27 +08:00
|
|
|
void *temp_p;
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
if (n == RT_NULL || buf == RT_NULL)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
return 0;
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
2019-06-05 14:49:19 +08:00
|
|
|
if (n->total < len)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
temp_p = rt_malloc(len);
|
|
|
|
if (temp_p == RT_NULL)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
rt_memset(temp_p, 0, len);
|
2019-05-24 20:04:27 +08:00
|
|
|
rt_free(n->p);
|
|
|
|
n->p = temp_p;
|
2019-06-05 14:49:19 +08:00
|
|
|
n->total = len;
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
2019-06-05 14:49:19 +08:00
|
|
|
cp_len = n->total > len ? len : n->total;
|
2019-05-24 20:04:27 +08:00
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
for(i = cp_len, j = 0; i > 0; i--, j++)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
n->p[j] = buf[i - 1];
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
return cp_len;
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief x = a + b
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param a bignum obj
|
|
|
|
* @param b bignum obj
|
|
|
|
* @param c bignum obj
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @return RT_EOK on success.
|
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *x,
|
|
|
|
const struct hw_bignum_mpi *a,
|
|
|
|
const struct hw_bignum_mpi *b)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
struct hwcrypto_bignum *bignum_ctx;
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
if (hwcrypto_bignum_dev_is_init() != RT_EOK)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
|
|
|
|
if (bignum_ctx->ops->add)
|
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
return bignum_ctx->ops->add(bignum_ctx, x, a, b);
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief x = a - b
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param a bignum obj
|
|
|
|
* @param b bignum obj
|
|
|
|
* @param c bignum obj
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @return RT_EOK on success.
|
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *x,
|
|
|
|
const struct hw_bignum_mpi *a,
|
|
|
|
const struct hw_bignum_mpi *b)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
struct hwcrypto_bignum *bignum_ctx;
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
if (hwcrypto_bignum_dev_is_init() != RT_EOK)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
|
|
|
|
if (bignum_ctx->ops->sub)
|
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
return bignum_ctx->ops->sub(bignum_ctx, x, a, b);
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief x = a * b
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param a bignum obj
|
|
|
|
* @param b bignum obj
|
|
|
|
* @param c bignum obj
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @return RT_EOK on success.
|
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *x,
|
|
|
|
const struct hw_bignum_mpi *a,
|
|
|
|
const struct hw_bignum_mpi *b)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
struct hwcrypto_bignum *bignum_ctx;
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
if (hwcrypto_bignum_dev_is_init() != RT_EOK)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
|
|
|
|
if (bignum_ctx->ops->mul)
|
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
return bignum_ctx->ops->mul(bignum_ctx, x, a, b);
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief x = a * b (mod c)
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param a bignum obj
|
|
|
|
* @param b bignum obj
|
|
|
|
* @param c bignum obj
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @return RT_EOK on success.
|
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *x,
|
|
|
|
const struct hw_bignum_mpi *a,
|
2019-05-24 20:04:27 +08:00
|
|
|
const struct hw_bignum_mpi *b,
|
2019-06-05 14:49:19 +08:00
|
|
|
const struct hw_bignum_mpi *c)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
struct hwcrypto_bignum *bignum_ctx;
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
if (hwcrypto_bignum_dev_is_init() != RT_EOK)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
|
|
|
|
if (bignum_ctx->ops->mulmod)
|
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
return bignum_ctx->ops->mulmod(bignum_ctx, x, a, b, c);
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-05 14:49:19 +08:00
|
|
|
* @brief x = a ^ b (mod c)
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @param a bignum obj
|
|
|
|
* @param b bignum obj
|
|
|
|
* @param c bignum obj
|
2021-03-08 18:19:04 +08:00
|
|
|
*
|
2019-05-24 20:04:27 +08:00
|
|
|
* @return RT_EOK on success.
|
|
|
|
*/
|
2019-06-05 14:49:19 +08:00
|
|
|
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)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
struct hwcrypto_bignum *bignum_ctx;
|
|
|
|
|
2019-06-05 14:49:19 +08:00
|
|
|
if (hwcrypto_bignum_dev_is_init() != RT_EOK)
|
2019-05-24 20:04:27 +08:00
|
|
|
{
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|
|
|
|
bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
|
|
|
|
if (bignum_ctx->ops->exptmod)
|
|
|
|
{
|
2019-06-05 14:49:19 +08:00
|
|
|
return bignum_ctx->ops->exptmod(bignum_ctx, x, a, b, c);
|
2019-05-24 20:04:27 +08:00
|
|
|
}
|
|
|
|
return -RT_ERROR;
|
|
|
|
}
|