FreeRTOS-Kernel/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/wc_dsp.c
TakayukiMatsuo 94aa31c3cb
Update wolfSSL to the latest version(v.4.4.0) (#186)
* 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>
2020-08-07 15:58:14 -07:00

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 */