mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-10-19 11:17:43 -04:00
* deleted old version wolfSSL before updating * updated wolfSSL to the latest version(v4.4.0) * updated wolfSSL to the latest version(v4.4.0) * added macros for timing resistance Co-authored-by: RichardBarry <3073890+RichardBarry@users.noreply.github.com> Co-authored-by: Ming Yue <mingyue86010@gmail.com>
327 lines
8.7 KiB
C
327 lines
8.7 KiB
C
/* wc_dsp.c
|
|
*
|
|
* Copyright (C) 2006-2020 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <wolfssl/wolfcrypt/settings.h>
|
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
|
#include <wolfssl/wolfcrypt/cpuid.h>
|
|
#include <wolfssl/wolfcrypt/logging.h>
|
|
#ifdef NO_INLINE
|
|
#include <wolfssl/wolfcrypt/misc.h>
|
|
#else
|
|
#define WOLFSSL_MISC_INCLUDED
|
|
#include <wolfcrypt/src/misc.c>
|
|
#endif
|
|
|
|
#if defined(WOLFSSL_DSP)
|
|
#include "remote.h"
|
|
#include "rpcmem.h"
|
|
static wolfSSL_DSP_Handle_cb handle_function = NULL;
|
|
static remote_handle64 defaultHandle;
|
|
static wolfSSL_Mutex handle_mutex; /* mutex for access to single default handle */
|
|
|
|
#define WOLFSSL_HANDLE_DONE 1
|
|
#define WOLFSSL_HANDLE_GET 0
|
|
|
|
/* callback function for setting the default handle in single threaded
|
|
* use cases */
|
|
static int default_handle_cb(remote_handle64 *handle, int finished, void *ctx)
|
|
{
|
|
(void)ctx;
|
|
if (finished == WOLFSSL_HANDLE_DONE) {
|
|
if (wc_UnLockMutex(&handle_mutex) != 0) {
|
|
WOLFSSL_MSG("Unlock handle mutex failed");
|
|
return -1;
|
|
}
|
|
}
|
|
else {
|
|
if (wc_LockMutex(&handle_mutex) != 0) {
|
|
WOLFSSL_MSG("Lock handle mutex failed");
|
|
return -1;
|
|
}
|
|
*handle = defaultHandle;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* Set global callback for getting handle to use
|
|
* return 0 on success */
|
|
int wolfSSL_SetHandleCb(wolfSSL_DSP_Handle_cb in)
|
|
{
|
|
handle_function = in;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* returns 1 if global handle callback is set and 0 if not */
|
|
int wolfSSL_GetHandleCbSet()
|
|
{
|
|
return (handle_function != NULL)? 1: 0;
|
|
}
|
|
|
|
|
|
/* Local function for setting up default handle
|
|
* returns 0 on success */
|
|
int wolfSSL_InitHandle()
|
|
{
|
|
char *sp_URI_value;
|
|
int ret;
|
|
|
|
sp_URI_value = wolfSSL_URI "&_dom=adsp";
|
|
ret = wolfSSL_open(sp_URI_value, &defaultHandle);
|
|
if (ret != 0) {
|
|
WOLFSSL_MSG("Unable to open aDSP?");
|
|
return -1;
|
|
}
|
|
wolfSSL_SetHandleCb(default_handle_cb);
|
|
ret = wc_InitMutex(&handle_mutex);
|
|
if (ret != 0) {
|
|
WOLFSSL_MSG("Unable to init handle mutex");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* internal function that closes default handle and frees mutex */
|
|
void wolfSSL_CleanupHandle()
|
|
{
|
|
wolfSSL_close(defaultHandle);
|
|
wc_FreeMutex(&handle_mutex);
|
|
}
|
|
#if defined(WOLFSSL_HAVE_SP_ECC)
|
|
|
|
/* ecc conversion from sp_c32.c */
|
|
#include <wolfssl/wolfcrypt/sp.h>
|
|
|
|
|
|
#ifndef WOLFSSL_SP_NO_256
|
|
|
|
#ifdef HAVE_ECC_VERIFY
|
|
/* Read big endian unsigned byte array into r.
|
|
*
|
|
* r A single precision integer.
|
|
* size Maximum number of bytes to convert
|
|
* a Byte array.
|
|
* n Number of bytes in array to read.
|
|
*/
|
|
static void int_256_from_bin(int32* r, int size, const byte* a, int n)
|
|
{
|
|
int i, j = 0;
|
|
word32 s = 0;
|
|
|
|
r[0] = 0;
|
|
for (i = n-1; i >= 0; i--) {
|
|
r[j] |= (((int32)a[i]) << s);
|
|
if (s >= 18U) {
|
|
r[j] &= 0x3ffffff;
|
|
s = 26U - s;
|
|
if (j + 1 >= size) {
|
|
break;
|
|
}
|
|
r[++j] = (int32)a[i] >> s;
|
|
s = 8U - s;
|
|
}
|
|
else {
|
|
s += 8U;
|
|
}
|
|
}
|
|
|
|
for (j++; j < size; j++) {
|
|
r[j] = 0;
|
|
}
|
|
}
|
|
|
|
/* Convert an mp_int to an array of sp_digit.
|
|
*
|
|
* r A single precision integer.
|
|
* size Maximum number of bytes to convert
|
|
* a A multi-precision integer.
|
|
*/
|
|
static void int_256_from_mp(int32* r, int size, const mp_int* a)
|
|
{
|
|
#if DIGIT_BIT == 26
|
|
int j;
|
|
|
|
XMEMCPY(r, a->dp, sizeof(int32) * a->used);
|
|
|
|
for (j = a->used; j < size; j++) {
|
|
r[j] = 0;
|
|
}
|
|
#elif DIGIT_BIT > 26
|
|
int i, j = 0;
|
|
word32 s = 0;
|
|
|
|
r[0] = 0;
|
|
for (i = 0; i < a->used && j < size; i++) {
|
|
r[j] |= ((int32)a->dp[i] << s);
|
|
r[j] &= 0x3ffffff;
|
|
s = 26U - s;
|
|
if (j + 1 >= size) {
|
|
break;
|
|
}
|
|
/* lint allow cast of mismatch word32 and mp_digit */
|
|
r[++j] = (int32)(a->dp[i] >> s); /*lint !e9033*/
|
|
while ((s + 26U) <= (word32)DIGIT_BIT) {
|
|
s += 26U;
|
|
r[j] &= 0x3ffffff;
|
|
if (j + 1 >= size) {
|
|
break;
|
|
}
|
|
if (s < (word32)DIGIT_BIT) {
|
|
/* lint allow cast of mismatch word32 and mp_digit */
|
|
r[++j] = (int32)(a->dp[i] >> s); /*lint !e9033*/
|
|
}
|
|
else {
|
|
r[++j] = 0L;
|
|
}
|
|
}
|
|
s = (word32)DIGIT_BIT - s;
|
|
}
|
|
|
|
for (j++; j < size; j++) {
|
|
r[j] = 0;
|
|
}
|
|
#else
|
|
int i, j = 0, s = 0;
|
|
|
|
r[0] = 0;
|
|
for (i = 0; i < a->used && j < size; i++) {
|
|
r[j] |= ((int32)a->dp[i]) << s;
|
|
if (s + DIGIT_BIT >= 26) {
|
|
r[j] &= 0x3ffffff;
|
|
if (j + 1 >= size) {
|
|
break;
|
|
}
|
|
s = 26 - s;
|
|
if (s == DIGIT_BIT) {
|
|
r[++j] = 0;
|
|
s = 0;
|
|
}
|
|
else {
|
|
r[++j] = a->dp[i] >> s;
|
|
s = DIGIT_BIT - s;
|
|
}
|
|
}
|
|
else {
|
|
s += DIGIT_BIT;
|
|
}
|
|
}
|
|
|
|
for (j++; j < size; j++) {
|
|
r[j] = 0;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* Verify the signature values with the hash and public key.
|
|
* e = Truncate(hash, 256)
|
|
* u1 = e/s mod order
|
|
* u2 = r/s mod order
|
|
* r == (u1.G + u2.Q)->x mod order
|
|
* Optimization: Leave point in projective form.
|
|
* (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
|
|
* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
|
|
* The hash is truncated to the first 256 bits.
|
|
*
|
|
* hash Hash to sign.
|
|
* hashLen Length of the hash data.
|
|
* rng Random number generator.
|
|
* priv Private part of key - scalar.
|
|
* rm First part of result as an mp_int.
|
|
* sm Sirst part of result as an mp_int.
|
|
* heap Heap to use for allocation.
|
|
* returns RNG failures, MEMORY_E when memory allocation fails and
|
|
* MP_OKAY on success.
|
|
*/
|
|
int sp_dsp_ecc_verify_256(remote_handle64 handleIn, const byte* hash, word32 hashLen, mp_int* pX,
|
|
mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)
|
|
{
|
|
int ret;
|
|
remote_handle64 handle = handleIn;
|
|
|
|
#if 0
|
|
/* calling to alloc memory on the ION using these settings slowed the performance down slightly */
|
|
int32 *x = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
|
|
int32 *y = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
|
|
int32 *z = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
|
|
int32 *s = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
|
|
int32 *u1 = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
|
|
int32 *u2 = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
|
|
#endif
|
|
int32 x[10] __attribute__((aligned(128)));
|
|
int32 y[10] __attribute__((aligned(128)));
|
|
int32 z[10] __attribute__((aligned(128)));
|
|
int32 s[10] __attribute__((aligned(128)));
|
|
int32 u1[10] __attribute__((aligned(128)));
|
|
int32 u2[10] __attribute__((aligned(128)));
|
|
|
|
if (hashLen > 32U) {
|
|
hashLen = 32U;
|
|
}
|
|
|
|
int_256_from_bin(u1, 10, hash, (int)hashLen);
|
|
int_256_from_mp(u2, 10, r);
|
|
int_256_from_mp(s, 10, sm);
|
|
int_256_from_mp(x, 10, pX);
|
|
int_256_from_mp(y, 10, pY);
|
|
int_256_from_mp(z, 10, pZ);
|
|
|
|
if (handle_function != NULL) {
|
|
handle_function(&handle, WOLFSSL_HANDLE_GET, NULL);
|
|
}
|
|
|
|
*res = 0;
|
|
ret = wolfSSL_DSP_ECC_Verify_256(handle, u1, 10, u2, 10, s, 10, x, 10, y, 10, z, 10, res);
|
|
|
|
if (handle_function != NULL) {
|
|
handle_function(&handle, WOLFSSL_HANDLE_DONE, NULL);
|
|
}
|
|
#if 0
|
|
rpcmem_free(x);
|
|
rpcmem_free(y);
|
|
rpcmem_free(z);
|
|
rpcmem_free(s);
|
|
rpcmem_free(u1);
|
|
rpcmem_free(u2);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* Used to assign a handle to an ecc_key structure.
|
|
* returns 0 on success */
|
|
int wc_ecc_set_handle(ecc_key* key, remote_handle64 handle)
|
|
{
|
|
if (key == NULL) {
|
|
return BAD_FUNC_ARG;
|
|
}
|
|
key->handle = handle;
|
|
return 0;
|
|
}
|
|
#endif /* HAVE_ECC_VERIFY */
|
|
#endif /* !WOLFSSL_SP_NO_256 */
|
|
#endif /* WOLFSSL_HAVE_SP_ECC */
|
|
#endif /* WOLFSSL_DSP */
|