wc_dsp.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* wc_dsp.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #include <wolfssl/wolfcrypt/error-crypt.h>
  26. #include <wolfssl/wolfcrypt/logging.h>
  27. #ifdef NO_INLINE
  28. #include <wolfssl/wolfcrypt/misc.h>
  29. #else
  30. #define WOLFSSL_MISC_INCLUDED
  31. #include <wolfcrypt/src/misc.c>
  32. #endif
  33. #if defined(WOLFSSL_DSP)
  34. #include "remote.h"
  35. #include "rpcmem.h"
  36. static wolfSSL_DSP_Handle_cb handle_function = NULL;
  37. static remote_handle64 defaultHandle;
  38. static wolfSSL_Mutex handle_mutex; /* mutex for access to single default handle */
  39. #define WOLFSSL_HANDLE_DONE 1
  40. #define WOLFSSL_HANDLE_GET 0
  41. /* callback function for setting the default handle in single threaded
  42. * use cases */
  43. static int default_handle_cb(remote_handle64 *handle, int finished, void *ctx)
  44. {
  45. (void)ctx;
  46. if (finished == WOLFSSL_HANDLE_DONE) {
  47. if (wc_UnLockMutex(&handle_mutex) != 0) {
  48. WOLFSSL_MSG("Unlock handle mutex failed");
  49. return -1;
  50. }
  51. }
  52. else {
  53. if (wc_LockMutex(&handle_mutex) != 0) {
  54. WOLFSSL_MSG("Lock handle mutex failed");
  55. return -1;
  56. }
  57. *handle = defaultHandle;
  58. }
  59. return 0;
  60. }
  61. /* Set global callback for getting handle to use
  62. * return 0 on success */
  63. int wolfSSL_SetHandleCb(wolfSSL_DSP_Handle_cb in)
  64. {
  65. handle_function = in;
  66. return 0;
  67. }
  68. /* returns 1 if global handle callback is set and 0 if not */
  69. int wolfSSL_GetHandleCbSet()
  70. {
  71. return (handle_function != NULL)? 1: 0;
  72. }
  73. /* Local function for setting up default handle
  74. * returns 0 on success */
  75. int wolfSSL_InitHandle()
  76. {
  77. char *sp_URI_value;
  78. int ret;
  79. sp_URI_value = wolfSSL_URI "&_dom=adsp";
  80. ret = wolfSSL_open(sp_URI_value, &defaultHandle);
  81. if (ret != 0) {
  82. WOLFSSL_MSG("Unable to open aDSP?");
  83. return -1;
  84. }
  85. wolfSSL_SetHandleCb(default_handle_cb);
  86. ret = wc_InitMutex(&handle_mutex);
  87. if (ret != 0) {
  88. WOLFSSL_MSG("Unable to init handle mutex");
  89. return -1;
  90. }
  91. return 0;
  92. }
  93. /* internal function that closes default handle and frees mutex */
  94. void wolfSSL_CleanupHandle()
  95. {
  96. wolfSSL_close(defaultHandle);
  97. wc_FreeMutex(&handle_mutex);
  98. }
  99. #if defined(WOLFSSL_HAVE_SP_ECC)
  100. /* ecc conversion from sp_c32.c */
  101. #include <wolfssl/wolfcrypt/sp.h>
  102. #ifndef WOLFSSL_SP_NO_256
  103. #ifdef HAVE_ECC_VERIFY
  104. /* Read big endian unsigned byte array into r.
  105. *
  106. * r A single precision integer.
  107. * size Maximum number of bytes to convert
  108. * a Byte array.
  109. * n Number of bytes in array to read.
  110. */
  111. static void int_256_from_bin(int32* r, int size, const byte* a, int n)
  112. {
  113. int i, j = 0;
  114. word32 s = 0;
  115. r[0] = 0;
  116. for (i = n-1; i >= 0; i--) {
  117. r[j] |= (((int32)a[i]) << s);
  118. if (s >= 18U) {
  119. r[j] &= 0x3ffffff;
  120. s = 26U - s;
  121. if (j + 1 >= size) {
  122. break;
  123. }
  124. r[++j] = (int32)a[i] >> s;
  125. s = 8U - s;
  126. }
  127. else {
  128. s += 8U;
  129. }
  130. }
  131. for (j++; j < size; j++) {
  132. r[j] = 0;
  133. }
  134. }
  135. /* Convert an mp_int to an array of sp_digit.
  136. *
  137. * r A single precision integer.
  138. * size Maximum number of bytes to convert
  139. * a A multi-precision integer.
  140. */
  141. static void int_256_from_mp(int32* r, int size, const mp_int* a)
  142. {
  143. #if DIGIT_BIT == 26
  144. int j;
  145. XMEMCPY(r, a->dp, sizeof(int32) * a->used);
  146. for (j = a->used; j < size; j++) {
  147. r[j] = 0;
  148. }
  149. #elif DIGIT_BIT > 26
  150. int i, j = 0;
  151. word32 s = 0;
  152. r[0] = 0;
  153. for (i = 0; i < a->used && j < size; i++) {
  154. r[j] |= ((int32)a->dp[i] << s);
  155. r[j] &= 0x3ffffff;
  156. s = 26U - s;
  157. if (j + 1 >= size) {
  158. break;
  159. }
  160. /* lint allow cast of mismatch word32 and mp_digit */
  161. r[++j] = (int32)(a->dp[i] >> s); /*lint !e9033*/
  162. while ((s + 26U) <= (word32)DIGIT_BIT) {
  163. s += 26U;
  164. r[j] &= 0x3ffffff;
  165. if (j + 1 >= size) {
  166. break;
  167. }
  168. if (s < (word32)DIGIT_BIT) {
  169. /* lint allow cast of mismatch word32 and mp_digit */
  170. r[++j] = (int32)(a->dp[i] >> s); /*lint !e9033*/
  171. }
  172. else {
  173. r[++j] = 0L;
  174. }
  175. }
  176. s = (word32)DIGIT_BIT - s;
  177. }
  178. for (j++; j < size; j++) {
  179. r[j] = 0;
  180. }
  181. #else
  182. int i, j = 0, s = 0;
  183. r[0] = 0;
  184. for (i = 0; i < a->used && j < size; i++) {
  185. r[j] |= ((int32)a->dp[i]) << s;
  186. if (s + DIGIT_BIT >= 26) {
  187. r[j] &= 0x3ffffff;
  188. if (j + 1 >= size) {
  189. break;
  190. }
  191. s = 26 - s;
  192. if (s == DIGIT_BIT) {
  193. r[++j] = 0;
  194. s = 0;
  195. }
  196. else {
  197. r[++j] = a->dp[i] >> s;
  198. s = DIGIT_BIT - s;
  199. }
  200. }
  201. else {
  202. s += DIGIT_BIT;
  203. }
  204. }
  205. for (j++; j < size; j++) {
  206. r[j] = 0;
  207. }
  208. #endif
  209. }
  210. /* Verify the signature values with the hash and public key.
  211. * e = Truncate(hash, 256)
  212. * u1 = e/s mod order
  213. * u2 = r/s mod order
  214. * r == (u1.G + u2.Q)->x mod order
  215. * Optimization: Leave point in projective form.
  216. * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
  217. * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
  218. * The hash is truncated to the first 256 bits.
  219. *
  220. * hash Hash to sign.
  221. * hashLen Length of the hash data.
  222. * rng Random number generator.
  223. * priv Private part of key - scalar.
  224. * rm First part of result as an mp_int.
  225. * sm Sirst part of result as an mp_int.
  226. * heap Heap to use for allocation.
  227. * returns RNG failures, MEMORY_E when memory allocation fails and
  228. * MP_OKAY on success.
  229. */
  230. int sp_dsp_ecc_verify_256(remote_handle64 handleIn, const byte* hash, word32 hashLen, mp_int* pX,
  231. mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)
  232. {
  233. int ret;
  234. remote_handle64 handle = handleIn;
  235. #if 0
  236. /* calling to alloc memory on the ION using these settings slowed the performance down slightly */
  237. int32 *x = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
  238. int32 *y = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
  239. int32 *z = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
  240. int32 *s = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
  241. int32 *u1 = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
  242. int32 *u2 = (int32*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 10*sizeof(int));
  243. #endif
  244. int32 x[10] __attribute__((aligned(128)));
  245. int32 y[10] __attribute__((aligned(128)));
  246. int32 z[10] __attribute__((aligned(128)));
  247. int32 s[10] __attribute__((aligned(128)));
  248. int32 u1[10] __attribute__((aligned(128)));
  249. int32 u2[10] __attribute__((aligned(128)));
  250. if (hashLen > 32U) {
  251. hashLen = 32U;
  252. }
  253. int_256_from_bin(u1, 10, hash, (int)hashLen);
  254. int_256_from_mp(u2, 10, r);
  255. int_256_from_mp(s, 10, sm);
  256. int_256_from_mp(x, 10, pX);
  257. int_256_from_mp(y, 10, pY);
  258. int_256_from_mp(z, 10, pZ);
  259. if (handle_function != NULL) {
  260. handle_function(&handle, WOLFSSL_HANDLE_GET, NULL);
  261. }
  262. *res = 0;
  263. ret = wolfSSL_DSP_ECC_Verify_256(handle, u1, 10, u2, 10, s, 10, x, 10, y, 10, z, 10, res);
  264. if (handle_function != NULL) {
  265. handle_function(&handle, WOLFSSL_HANDLE_DONE, NULL);
  266. }
  267. #if 0
  268. rpcmem_free(x);
  269. rpcmem_free(y);
  270. rpcmem_free(z);
  271. rpcmem_free(s);
  272. rpcmem_free(u1);
  273. rpcmem_free(u2);
  274. #endif
  275. return ret;
  276. }
  277. /* Used to assign a handle to an ecc_key structure.
  278. * returns 0 on success */
  279. int wc_ecc_set_handle(ecc_key* key, remote_handle64 handle)
  280. {
  281. if (key == NULL) {
  282. return BAD_FUNC_ARG;
  283. }
  284. key->handle = handle;
  285. return 0;
  286. }
  287. #endif /* HAVE_ECC_VERIFY */
  288. #endif /* !WOLFSSL_SP_NO_256 */
  289. #endif /* WOLFSSL_HAVE_SP_ECC */
  290. #endif /* WOLFSSL_DSP */