| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- /* wc_dsp.c
- *
- * Copyright (C) 2006-2023 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/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 */
|