CARPLAY版本整理
This commit is contained in:
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
# dummy
|
@ -0,0 +1 @@
|
||||
See caam_doc.pdf for documentation about building and using.
|
@ -0,0 +1,665 @@
|
||||
/* caam_aes.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>
|
||||
|
||||
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_AES) && \
|
||||
!defined(NO_IMX6_CAAM_AES)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
int wc_AesSetKey(Aes* aes, const byte* key, word32 len,
|
||||
const byte* iv, int dir)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (len > 32) {
|
||||
byte out[32]; /* max AES key size */
|
||||
word32 outSz;
|
||||
|
||||
if (len != 64 && len != 72 && len != 80) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
outSz = sizeof(out);
|
||||
/* if length greater then 32 then try to unencapsulate */
|
||||
if ((ret = wc_caamOpenBlob((byte*)key, len, out, &outSz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY((byte*)aes->key, out, outSz);
|
||||
aes->keylen = outSz;
|
||||
}
|
||||
else {
|
||||
if (len != 16 && len != 24 && len != 32) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMCPY((byte*)aes->key, key, len);
|
||||
aes->keylen = len;
|
||||
}
|
||||
|
||||
switch (aes->keylen) {
|
||||
case 16: aes->rounds = 10; break;
|
||||
case 24: aes->rounds = 12; break;
|
||||
case 32: aes->rounds = 14; break;
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesSetIV(aes, iv)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
aes->left = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesCbcEncrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz)
|
||||
{
|
||||
word32 blocks;
|
||||
|
||||
WOLFSSL_ENTER("wc_AesCbcEncrypt");
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
if (blocks > 0) {
|
||||
Buffer buf[4];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret;
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)aes->reg;
|
||||
buf[1].Length = AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (Address)in;
|
||||
buf[2].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
||||
buf[3].TheAddress = (Address)out;
|
||||
buf[3].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = CAAM_ENC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, 4, arg, CAAM_AESCBC)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES CBC encrypt");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesCbcDecrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz)
|
||||
{
|
||||
word32 blocks;
|
||||
|
||||
WOLFSSL_ENTER("wc_AesCbcDecrypt");
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
if (blocks > 0) {
|
||||
Buffer buf[4];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret;
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)aes->reg;
|
||||
buf[1].Length = AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (Address)in;
|
||||
buf[2].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
||||
buf[3].TheAddress = (Address)out;
|
||||
buf[3].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = CAAM_DEC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCBC)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES CBC decrypt");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(HAVE_AES_ECB)
|
||||
/* is assumed that input size is a multiple of AES_BLOCK_SIZE */
|
||||
int wc_AesEcbEncrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz)
|
||||
{
|
||||
word32 blocks;
|
||||
Buffer buf[3];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)in;
|
||||
buf[1].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer | LastBuffer;
|
||||
buf[2].TheAddress = (Address)out;
|
||||
buf[2].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = CAAM_ENC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESECB)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES ECB encrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesEcbDecrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz)
|
||||
{
|
||||
word32 blocks;
|
||||
Buffer buf[3];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)in;
|
||||
buf[1].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer | LastBuffer;
|
||||
buf[2].TheAddress = (Address)out;
|
||||
buf[2].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = CAAM_DEC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESECB)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES ECB decrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* AES-CTR */
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
/* Increment AES counter (from wolfcrypt/src/aes.c) */
|
||||
static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
|
||||
{
|
||||
/* in network byte order so start at end and work back */
|
||||
int i;
|
||||
for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
|
||||
if (++inOutCtr[i]) /* we're done unless we overflow */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int wc_AesCtrEncrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz)
|
||||
{
|
||||
byte* tmp;
|
||||
Buffer buf[4];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret, blocks;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* consume any unused bytes left in aes->tmp */
|
||||
tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
|
||||
while (aes->left && sz) {
|
||||
*(out++) = *(in++) ^ *(tmp++);
|
||||
aes->left--;
|
||||
sz--;
|
||||
}
|
||||
|
||||
/* do full blocks to then get potential left over amount */
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
if (blocks > 0) {
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)aes->reg;
|
||||
buf[1].Length = AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (Address)in;
|
||||
buf[2].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
||||
buf[3].TheAddress = (Address)out;
|
||||
buf[3].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = CAAM_ENC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCTR)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES CTR encrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
out += blocks * AES_BLOCK_SIZE;
|
||||
in += blocks * AES_BLOCK_SIZE;
|
||||
sz -= blocks * AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (sz) {
|
||||
if ((ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg)) != 0)
|
||||
return ret;
|
||||
IncrementAesCounter((byte*)aes->reg);
|
||||
|
||||
aes->left = AES_BLOCK_SIZE;
|
||||
tmp = (byte*)aes->tmp;
|
||||
|
||||
while (sz--) {
|
||||
*(out++) = *(in++) ^ *(tmp++);
|
||||
aes->left--;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* AES-DIRECT */
|
||||
#if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
|
||||
int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
|
||||
{
|
||||
Buffer buf[3];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)in;
|
||||
buf[1].Length = AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer | LastBuffer;
|
||||
buf[2].TheAddress = (Address)out;
|
||||
buf[2].Length = AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = CAAM_ENC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESECB)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES direct encrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
|
||||
{
|
||||
Buffer buf[3];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)in;
|
||||
buf[1].Length = AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer | LastBuffer;
|
||||
buf[2].TheAddress = (Address)out;
|
||||
buf[2].Length = AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = CAAM_DEC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = AES_BLOCK_SIZE;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESECB)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES direct decrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
|
||||
const byte* iv, int dir)
|
||||
{
|
||||
return wc_AesSetKey(aes, key, len, iv, dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AESCCM
|
||||
int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 inSz,
|
||||
const byte* nonce, word32 nonceSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
Buffer buf[5];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
word32 i;
|
||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||
int lenSz;
|
||||
byte mask = 0xFF;
|
||||
const word32 wordSz = (word32)sizeof(word32);
|
||||
int ret;
|
||||
|
||||
/* sanity check on arguments */
|
||||
if (aes == NULL || out == NULL || in == NULL || nonce == NULL
|
||||
|| authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
|
||||
authTagSz > AES_BLOCK_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if ((ret = wc_AesCcmCheckTagSize(authTagSz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set up B0 and CTR0 similar to how wolfcrypt/src/aes.c does */
|
||||
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
||||
XMEMCPY(B0Ctr0+AES_BLOCK_SIZE+1, nonce, nonceSz);
|
||||
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
||||
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
||||
+ (8 * (((byte)authTagSz - 2) / 2))
|
||||
+ (lenSz - 1);
|
||||
for (i = 0; i < lenSz; i++) {
|
||||
if (mask && i >= wordSz)
|
||||
mask = 0x00;
|
||||
B0Ctr0[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
|
||||
B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE - 1 - i] = 0;
|
||||
}
|
||||
B0Ctr0[AES_BLOCK_SIZE] = lenSz - 1;
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)B0Ctr0;
|
||||
buf[1].Length = AES_BLOCK_SIZE + AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (Address)authIn;
|
||||
buf[2].Length = authInSz;
|
||||
|
||||
buf[3].BufferType = DataBuffer;
|
||||
buf[3].TheAddress = (Address)in;
|
||||
buf[3].Length = inSz;
|
||||
|
||||
buf[4].BufferType = DataBuffer | LastBuffer;
|
||||
buf[4].TheAddress = (Address)out;
|
||||
buf[4].Length = inSz;
|
||||
|
||||
arg[0] = CAAM_ENC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = inSz;
|
||||
arg[3] = authInSz;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES-CCM encrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(authTag, B0Ctr0, authTagSz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 inSz,
|
||||
const byte* nonce, word32 nonceSz,
|
||||
const byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
Buffer buf[5];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
word32 i;
|
||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||
byte tag[AES_BLOCK_SIZE];
|
||||
int lenSz;
|
||||
byte mask = 0xFF;
|
||||
const word32 wordSz = (word32)sizeof(word32);
|
||||
int ret;
|
||||
|
||||
/* sanity check on arguments */
|
||||
if (aes == NULL || out == NULL || in == NULL || nonce == NULL
|
||||
|| authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
|
||||
authTagSz > AES_BLOCK_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if ((ret = wc_AesCcmCheckTagSize(authTagSz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set up B0 and CTR0 similar to how wolfcrypt/src/aes.c does */
|
||||
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
||||
XMEMCPY(B0Ctr0+AES_BLOCK_SIZE+1, nonce, nonceSz);
|
||||
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
||||
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
||||
+ (8 * (((byte)authTagSz - 2) / 2))
|
||||
+ (lenSz - 1);
|
||||
for (i = 0; i < lenSz; i++) {
|
||||
if (mask && i >= wordSz)
|
||||
mask = 0x00;
|
||||
B0Ctr0[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
|
||||
B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE - 1 - i] = 0;
|
||||
}
|
||||
B0Ctr0[AES_BLOCK_SIZE] = lenSz - 1;
|
||||
if ((ret = wc_AesEncryptDirect(aes, tag, B0Ctr0 + AES_BLOCK_SIZE)) != 0)
|
||||
return ret;
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)aes->key;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (Address)B0Ctr0;
|
||||
buf[1].Length = AES_BLOCK_SIZE + AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (Address)authIn;
|
||||
buf[2].Length = authInSz;
|
||||
|
||||
buf[3].BufferType = DataBuffer;
|
||||
buf[3].TheAddress = (Address)in;
|
||||
buf[3].Length = inSz;
|
||||
|
||||
buf[4].BufferType = DataBuffer | LastBuffer;
|
||||
buf[4].TheAddress = (Address)out;
|
||||
buf[4].Length = inSz;
|
||||
|
||||
arg[0] = CAAM_DEC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = inSz;
|
||||
arg[3] = authInSz;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES-CCM derypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
xorbuf(tag, B0Ctr0, authTagSz);
|
||||
if (ConstantCompare(tag, authTag, authTagSz) != 0) {
|
||||
/* If the authTag check fails, don't keep the decrypted data.
|
||||
* Unfortunately, you need the decrypted data to calculate the
|
||||
* check value. */
|
||||
XMEMSET(out, 0, inSz);
|
||||
ret = AES_CCM_AUTH_E;
|
||||
}
|
||||
|
||||
ForceZero(tag, AES_BLOCK_SIZE);
|
||||
ForceZero(B0Ctr0, AES_BLOCK_SIZE * 2);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
#endif /* HAVE_AESCCM */
|
||||
|
||||
#endif /* WOLFSSL_IMX6_CAAM && !NO_AES */
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,228 @@
|
||||
/* caam_error.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
|
||||
*/
|
||||
|
||||
#if (defined(__INTEGRITY) || defined(INTEGRITY)) || \
|
||||
(defined(__QNX__) || defined(__QNXNTO__))
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/caam_error.h>
|
||||
|
||||
/* return a negative value if CAAM reset needed */
|
||||
int caamParseCCBError(unsigned int error)
|
||||
{
|
||||
int ret = 0;
|
||||
switch((error >> 4) & 0xF) {
|
||||
case 0:
|
||||
WOLFSSL_MSG("\tCHAID: CCB");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
WOLFSSL_MSG("\tCHAID: AESA");
|
||||
switch (error & 0xF) {
|
||||
case 0xC:
|
||||
WOLFSSL_MSG("\tAAD size error");
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
WOLFSSL_MSG("\tCHAID: DESA");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
WOLFSSL_MSG("\tCHAID: AFHA (ARC4)");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
WOLFSSL_MSG("\tCHAID: MDHA hash");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
WOLFSSL_MSG("\tCHAID: RNG - ERRID:");
|
||||
ret = -1; /* treat RNG errors as fatal */
|
||||
switch(error & 0xF) {
|
||||
case 3:
|
||||
WOLFSSL_MSG("\tRNG instantiate error");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
WOLFSSL_MSG("\tRNG not instantiated error");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
WOLFSSL_MSG("\tRNG test instantiate error");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
WOLFSSL_MSG("\tRNG prediction resistance error");
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("\tUnknown");
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
WOLFSSL_MSG("\tCHAID: PKHA");
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("\tCHAID: Unknown CCB error");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* return a negative value for an error that requires CAAM reset */
|
||||
int caamParseDECOError(unsigned int error)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (error & 0xFF) {
|
||||
case 0x04:
|
||||
WOLFSSL_MSG("\tInvalid Descriptor Command");
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
WOLFSSL_MSG("\tInvalid KEY Command");
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
WOLFSSL_MSG("\tInvalid Load Command");
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
WOLFSSL_MSG("\tInvalid Store Command");
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
WOLFSSL_MSG("\tInvalid Operation Command");
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
WOLFSSL_MSG("\tInvalid PRB setting");
|
||||
break;
|
||||
|
||||
case 0x86:
|
||||
WOLFSSL_MSG("\tVerify ECC/RSA signature fail");
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("\tUnknown error");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* return a negative value if CAAM should be reset after error */
|
||||
int caamParseError(unsigned int error)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* print out of index of error
|
||||
unsigned int idx;
|
||||
idx = (error >> 8) & 0xFF;
|
||||
printf("idx of error = %d\n", idx);
|
||||
*/
|
||||
|
||||
if ((error & 0x40000000) > 0) {
|
||||
WOLFSSL_MSG("[DECO Error]");
|
||||
ret = caamParseDECOError(error);
|
||||
}
|
||||
|
||||
if ((error & 0x20000000) > 0) {
|
||||
WOLFSSL_MSG("[CCB Error]");
|
||||
ret = caamParseCCBError(error);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* parses a Job Ring Interrupt Status report
|
||||
* returns 0 if there is no error */
|
||||
unsigned int caamParseJRError(unsigned int error)
|
||||
{
|
||||
unsigned int err = (error >> 8) & 0x1F;
|
||||
|
||||
if (error & 0x10) {
|
||||
WOLFSSL_MSG("Job Ring Interrupt ENTER_FAIL");
|
||||
}
|
||||
|
||||
if (error & 0x20) {
|
||||
WOLFSSL_MSG("Job Ring Interrupt EXIT_FAIL");
|
||||
}
|
||||
|
||||
switch (err) {
|
||||
case 0x00:
|
||||
/* no error */
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
WOLFSSL_MSG("Error writing status to output ring");
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
WOLFSSL_MSG("Bad input ring address");
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
WOLFSSL_MSG("Bad output ring address");
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
WOLFSSL_MSG("Fatal, invalid write to input ring");
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
WOLFSSL_MSG("Invalid write to output ring");
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
WOLFSSL_MSG("Job ring released before halted");
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
WOLFSSL_MSG("Removed too many jobs");
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
WOLFSSL_MSG("Added too many jobs");
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown error");
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_CAAM_PRINT
|
||||
void DEBUG_PRINT_ARRAY(void* a, int aSz, char* str)
|
||||
{
|
||||
int i;
|
||||
unsigned char* pt = (unsigned char*)a;
|
||||
|
||||
printf("%s [%d] : ", str, aSz);
|
||||
for (i = 0; i < aSz; i++)
|
||||
printf("%02X", pt[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
1778
MXC_A27-PCB4.5-270S/lib/wolfssl/wolfcrypt/src/port/caam/caam_qnx.c
Normal file
1778
MXC_A27-PCB4.5-270S/lib/wolfssl/wolfcrypt/src/port/caam/caam_qnx.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,401 @@
|
||||
/* caam_sha.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>
|
||||
|
||||
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
#include <INTEGRITY.h>
|
||||
#endif
|
||||
#include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
#include <wolfssl/wolfcrypt/sha.h>
|
||||
#endif
|
||||
|
||||
#if !defined(NO_SHA256) || defined(WOLFSSL_SHA224)
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
|
||||
#include <wolfssl/wolfcrypt/sha512.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_MD5
|
||||
#include <wolfssl/wolfcrypt/md5.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
Common Code Between SHA Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int _InitSha(wc_Sha* sha, void* heap, int devId, word32 digestSz,
|
||||
word32 type)
|
||||
{
|
||||
Buffer buf[1];
|
||||
word32 arg[4];
|
||||
int ret;
|
||||
|
||||
(void)heap;
|
||||
(void)devId;
|
||||
|
||||
if (sha == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMSET(sha, 0, sizeof(Sha));
|
||||
|
||||
/* Set buffer for context */
|
||||
buf[0].BufferType = DataBuffer | LastBuffer;
|
||||
buf[0].TheAddress = (Address)sha->ctx;
|
||||
buf[0].Length = digestSz + WC_CAAM_CTXLEN;
|
||||
buf[0].Transferred = 0;
|
||||
|
||||
arg[0] = CAAM_ALG_INIT;
|
||||
arg[1] = digestSz + WC_CAAM_CTXLEN;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM SHA init");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _ShaUpdate(wc_Sha* sha, const byte* data, word32 len, word32 digestSz,
|
||||
word32 type)
|
||||
{
|
||||
Buffer buf[2];
|
||||
word32 arg[4];
|
||||
int ret;
|
||||
byte* local;
|
||||
|
||||
if (sha == NULL ||(data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (len == 0) return 0; /* nothing to do */
|
||||
|
||||
local = (byte*)sha->buffer;
|
||||
/* check for filling out existing buffer */
|
||||
if (sha->buffLen > 0) {
|
||||
word32 add = min(len, WC_CAAM_HASH_BLOCK - sha->buffLen);
|
||||
XMEMCPY(&local[sha->buffLen], data, add);
|
||||
|
||||
sha->buffLen += add;
|
||||
data += add;
|
||||
len -= add;
|
||||
|
||||
if (sha->buffLen == WC_CAAM_HASH_BLOCK) {
|
||||
/* Set buffer for context */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)sha->ctx;
|
||||
buf[0].Length = digestSz + WC_CAAM_CTXLEN;
|
||||
buf[0].Transferred = 0;
|
||||
|
||||
/* data to update with */
|
||||
buf[1].BufferType = DataBuffer | LastBuffer;
|
||||
buf[1].TheAddress = (Address)sha->buffer;
|
||||
buf[1].Length = sha->buffLen;
|
||||
buf[1].Transferred = 0;
|
||||
|
||||
arg[0] = CAAM_ALG_UPDATE;
|
||||
arg[1] = digestSz + WC_CAAM_CTXLEN;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM SHA update");
|
||||
return ret;
|
||||
}
|
||||
sha->buffLen = 0; /* cleared out buffer */
|
||||
}
|
||||
}
|
||||
|
||||
/* check if multiple full blocks can be done */
|
||||
if (len >= WC_CAAM_HASH_BLOCK) {
|
||||
word32 sz = len / WC_CAAM_HASH_BLOCK;
|
||||
sz = sz * WC_CAAM_HASH_BLOCK;
|
||||
|
||||
/* Set buffer for context */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)sha->ctx;
|
||||
buf[0].Length = digestSz + WC_CAAM_CTXLEN;
|
||||
buf[0].Transferred = 0;
|
||||
|
||||
/* data to update with */
|
||||
buf[1].BufferType = DataBuffer | LastBuffer;
|
||||
buf[1].TheAddress = (Address)data;
|
||||
buf[1].Length = sz;
|
||||
buf[1].Transferred = 0;
|
||||
|
||||
arg[0] = CAAM_ALG_UPDATE;
|
||||
arg[1] = digestSz + WC_CAAM_CTXLEN;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM SHA update");
|
||||
return ret;
|
||||
}
|
||||
|
||||
len -= sz;
|
||||
data += sz;
|
||||
}
|
||||
|
||||
/* check for left overs */
|
||||
if (len > 0) {
|
||||
word32 add = min(len, WC_CAAM_HASH_BLOCK - sha->buffLen);
|
||||
XMEMCPY(&local[sha->buffLen], data, add);
|
||||
sha->buffLen += add;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _ShaFinal(wc_Sha* sha, byte* out, word32 digestSz,
|
||||
word32 type)
|
||||
{
|
||||
Buffer buf[2];
|
||||
word32 arg[4];
|
||||
int ret;
|
||||
|
||||
if (sha == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Set buffer for context */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (Address)sha->ctx;
|
||||
buf[0].Length = digestSz + WC_CAAM_CTXLEN;
|
||||
buf[0].Transferred = 0;
|
||||
|
||||
/* add any potential left overs */
|
||||
buf[1].BufferType = DataBuffer | LastBuffer;
|
||||
buf[1].TheAddress = (Address)sha->buffer;
|
||||
buf[1].Length = sha->buffLen;
|
||||
buf[1].Transferred = 0;
|
||||
|
||||
arg[0] = CAAM_ALG_FINAL;
|
||||
arg[1] = digestSz + WC_CAAM_CTXLEN;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM SHA init");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
MD5
|
||||
****************************************************************************/
|
||||
#if !defined(NO_MD5)
|
||||
int wc_InitMd5_ex(wc_Md5* sha, void* heap, int devId)
|
||||
{
|
||||
return _InitSha(sha, heap, devId, MD5_DIGEST_SIZE, CAAM_MD5);
|
||||
}
|
||||
|
||||
|
||||
int wc_Md5Update(wc_Md5* sha, const byte* data, word32 len)
|
||||
{
|
||||
return _ShaUpdate(sha, data, len, MD5_DIGEST_SIZE, CAAM_MD5);
|
||||
}
|
||||
|
||||
|
||||
int wc_Md5Final(wc_Md5* sha, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = _ShaFinal(sha, hash, MD5_DIGEST_SIZE, CAAM_MD5)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(hash, (byte*)sha->ctx, MD5_DIGEST_SIZE);
|
||||
return _InitSha(sha, NULL, 0, MD5_DIGEST_SIZE, CAAM_MD5);
|
||||
}
|
||||
#endif /* !NO_MD5 */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 1
|
||||
****************************************************************************/
|
||||
#if !defined(NO_SHA)
|
||||
int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
|
||||
{
|
||||
return _InitSha(sha, heap, devId, SHA_DIGEST_SIZE, CAAM_SHA);
|
||||
}
|
||||
|
||||
|
||||
int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
|
||||
{
|
||||
return _ShaUpdate(sha, data, len, SHA_DIGEST_SIZE, CAAM_SHA);
|
||||
}
|
||||
|
||||
|
||||
int wc_ShaFinal(wc_Sha* sha, byte* out)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = _ShaFinal(sha, out, SHA_DIGEST_SIZE, CAAM_SHA)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(out, (byte*)sha->ctx, SHA_DIGEST_SIZE);
|
||||
return _InitSha(sha, NULL, 0, SHA_DIGEST_SIZE, CAAM_SHA);
|
||||
}
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 224
|
||||
****************************************************************************/
|
||||
#ifdef WOLFSSL_SHA224
|
||||
int wc_InitSha224_ex(wc_Sha224* sha, void* heap, int devId)
|
||||
{
|
||||
return _InitSha(sha, heap, devId, SHA256_DIGEST_SIZE, CAAM_SHA224);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha224Update(wc_Sha224* sha, const byte* data, word32 len)
|
||||
{
|
||||
return _ShaUpdate(sha, data, len, SHA256_DIGEST_SIZE, CAAM_SHA224);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha224Final(wc_Sha224* sha, byte* out)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = _ShaFinal(sha, out, SHA256_DIGEST_SIZE, CAAM_SHA224)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(out, (byte*)sha->ctx, SHA224_DIGEST_SIZE);
|
||||
return _InitSha(sha, NULL, 0, SHA256_DIGEST_SIZE, CAAM_SHA224);
|
||||
}
|
||||
#endif /* WOLFSSL_SHA224 */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 256
|
||||
****************************************************************************/
|
||||
#if !defined(NO_SHA256)
|
||||
int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId)
|
||||
{
|
||||
return _InitSha(sha, heap, devId, SHA256_DIGEST_SIZE, CAAM_SHA256);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha256Update(wc_Sha256* sha, const byte* data, word32 len)
|
||||
{
|
||||
return _ShaUpdate(sha, data, len, SHA256_DIGEST_SIZE, CAAM_SHA256);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha256Final(wc_Sha256* sha, byte* out)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = _ShaFinal(sha, out, SHA256_DIGEST_SIZE, CAAM_SHA256)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(out, (byte*)sha->ctx, SHA256_DIGEST_SIZE);
|
||||
return _InitSha(sha, NULL, 0, SHA256_DIGEST_SIZE, CAAM_SHA256);
|
||||
}
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 384
|
||||
****************************************************************************/
|
||||
#ifdef WOLFSSL_SHA384
|
||||
int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devId)
|
||||
{
|
||||
return _InitSha(sha, heap, devId, SHA512_DIGEST_SIZE, CAAM_SHA384);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha384Update(wc_Sha384* sha, const byte* data, word32 len)
|
||||
{
|
||||
return _ShaUpdate(sha, data, len, SHA512_DIGEST_SIZE, CAAM_SHA384);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha384Final(wc_Sha384* sha, byte* out)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = _ShaFinal(sha, out, SHA512_DIGEST_SIZE, CAAM_SHA384)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(out, (byte*)sha->ctx, SHA384_DIGEST_SIZE);
|
||||
return _InitSha(sha, NULL, 0, SHA512_DIGEST_SIZE, CAAM_SHA384);
|
||||
}
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 512
|
||||
****************************************************************************/
|
||||
#ifdef WOLFSSL_SHA512
|
||||
int wc_InitSha512_ex(wc_Sha512* sha, void* heap, int devId)
|
||||
{
|
||||
return _InitSha(sha, heap, devId, SHA512_DIGEST_SIZE, CAAM_SHA512);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha512Update(wc_Sha512* sha, const byte* data, word32 len)
|
||||
{
|
||||
return _ShaUpdate(sha, data, len, SHA512_DIGEST_SIZE, CAAM_SHA512);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha512Final(wc_Sha512* sha, byte* out)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = _ShaFinal(sha, out, SHA512_DIGEST_SIZE, CAAM_SHA512)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(out, (byte*)sha->ctx, SHA512_DIGEST_SIZE);
|
||||
return _InitSha(sha, NULL, 0, SHA512_DIGEST_SIZE, CAAM_SHA512);
|
||||
}
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
|
||||
#endif /* WOLFSSL_IMX6_CAAM && !NO_IMX6_CAAM_HASH */
|
@ -0,0 +1,450 @@
|
||||
/* wolfcaam_aes.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>
|
||||
|
||||
#if defined(WOLFSSL_CAAM) && !defined(NO_AES)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_aes.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#if (defined(HAVE_AESGCM) && defined(WOLFSSL_CAAM_AESGCM)) || \
|
||||
defined(HAVE_AESCCM)
|
||||
/* return 0 on success */
|
||||
static int wc_CAAM_AesAeadCommon(Aes* aes, const byte* in, byte* out, word32 sz,
|
||||
const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz, int dir, int type)
|
||||
{
|
||||
CAAM_BUFFER buf[7];
|
||||
int ret, idx = 0;
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
|
||||
if (aes == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (wc_AesGetKeySize(aes, &keySz) != 0 && aes->blackKey == 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)aes->devKey;
|
||||
buf[idx].Length = keySz;
|
||||
idx++;
|
||||
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)nonce;
|
||||
buf[idx].Length = nonceSz;
|
||||
idx++;
|
||||
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)in;
|
||||
buf[idx].Length = sz;
|
||||
idx++;
|
||||
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)out;
|
||||
buf[idx].Length = sz;
|
||||
idx++;
|
||||
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)authTag;
|
||||
buf[idx].Length = authTagSz;
|
||||
idx++;
|
||||
|
||||
buf[idx].BufferType = DataBuffer | LastBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)authIn;
|
||||
buf[idx].Length = authInSz;
|
||||
idx++;
|
||||
|
||||
/* authInSz must fit into a short (note that only 16 bits are ava in CAAM
|
||||
* for AAD size anyway) */
|
||||
arg[0] = ((authInSz & 0xFFFF) << 16) | (dir & 0xFFFF);
|
||||
arg[1] = ((nonceSz & 0xFF) << 24) | ((authTagSz & 0xFF) << 16) |
|
||||
(keySz & 0xFFFF);
|
||||
arg[2] = sz;
|
||||
arg[3] = aes->blackKey;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, idx, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES AEAD operation");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_AESGCM || HAVE_AESCCM */
|
||||
|
||||
|
||||
#if defined(HAVE_AESCCM)
|
||||
#ifndef WOLFSSL_SECO_CAAM
|
||||
/* B0 is [ reserved | adata | M | L ] [ nonce ] [ l(m) ]
|
||||
* Ctr is current counter
|
||||
*/
|
||||
static word32 CreateB0CTR(byte* B0Ctr0, const byte* nonce, word32 nonceSz,
|
||||
word32 authInSz, word32 authTagSz, word32 inSz)
|
||||
{
|
||||
word32 i;
|
||||
word32 lenSz;
|
||||
byte mask = 0xFF;
|
||||
const word32 wordSz = (word32)sizeof(word32);
|
||||
|
||||
/* set up B0 and CTR0 similar to how wolfcrypt/src/aes.c does */
|
||||
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
||||
XMEMCPY(B0Ctr0+AES_BLOCK_SIZE+1, nonce, nonceSz);
|
||||
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
||||
B0Ctr0[0] = 0;
|
||||
if (authInSz > 0) {
|
||||
B0Ctr0[0] |= 0x40; /* set aad bit */
|
||||
}
|
||||
|
||||
/* add size of tag encoded as (sz - 2)/2 (i.e M) */
|
||||
B0Ctr0[0] |= (((byte)authTagSz - 2) / 2) << 3;
|
||||
|
||||
/* size of l(m) */
|
||||
B0Ctr0[0] |= lenSz - 1;
|
||||
|
||||
/* add in l(m), length of message to be encrypted and sent */
|
||||
for (i = 0; i < lenSz; i++) {
|
||||
if (mask && i >= wordSz)
|
||||
mask = 0x00;
|
||||
B0Ctr0[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
|
||||
B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE - 1 - i] = 0;
|
||||
}
|
||||
B0Ctr0[AES_BLOCK_SIZE] = lenSz - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* plaintext in ciphertext and mac out
|
||||
* return 0 on success
|
||||
*/
|
||||
int wc_CAAM_AesCcmEncrypt(Aes* aes, const byte* in, byte* out, word32 sz,
|
||||
const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
#ifndef WOLFSSL_SECO_CAAM
|
||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||
#endif
|
||||
|
||||
if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
|
||||
nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
|
||||
authTagSz > AES_BLOCK_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* sanity check on tag size */
|
||||
if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_SECO_CAAM
|
||||
CreateB0CTR(B0Ctr0, nonce, nonceSz, authInSz, authTagSz, sz);
|
||||
return wc_CAAM_AesAeadCommon(aes, in, out, sz, B0Ctr0, 2*AES_BLOCK_SIZE,
|
||||
authTag, authTagSz, authIn, authInSz, CAAM_ENC, CAAM_AESCCM);
|
||||
#else
|
||||
return wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz,
|
||||
authTag, authTagSz, authIn, authInSz, CAAM_ENC, CAAM_AESCCM);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ciphertext in plaintext out
|
||||
* return 0 on success
|
||||
*/
|
||||
int wc_CAAM_AesCcmDecrypt(Aes* aes, const byte* in, byte* out, word32 sz,
|
||||
const byte* nonce, word32 nonceSz, const byte* authTag,
|
||||
word32 authTagSz, const byte* authIn, word32 authInSz)
|
||||
{
|
||||
int ret;
|
||||
#ifndef WOLFSSL_SECO_CAAM
|
||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||
#endif
|
||||
|
||||
/* sanity check on arguments */
|
||||
if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
|
||||
nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
|
||||
authTagSz > AES_BLOCK_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* sanity check on tag size */
|
||||
if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_SECO_CAAM
|
||||
CreateB0CTR(B0Ctr0, nonce, nonceSz, authInSz, authTagSz, sz);
|
||||
ret = wc_CAAM_AesAeadCommon(aes, in, out, sz, B0Ctr0, 2*AES_BLOCK_SIZE,
|
||||
(byte*)authTag, authTagSz, authIn, authInSz, CAAM_DEC, CAAM_AESCCM);
|
||||
#else
|
||||
ret = wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz,
|
||||
(byte*)authTag, authTagSz, authIn, authInSz, CAAM_DEC, CAAM_AESCCM);
|
||||
#endif
|
||||
|
||||
if (ret != 0) {
|
||||
/* If the authTag check fails, don't keep the decrypted data.
|
||||
* Unfortunately, you need the decrypted data to calculate the
|
||||
* check value. */
|
||||
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) && \
|
||||
defined(ACVP_VECTOR_TESTING)
|
||||
WOLFSSL_MSG("Preserve output for vector responses");
|
||||
#else
|
||||
if (sz > 0)
|
||||
XMEMSET(out, 0, sz);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_AESCCM */
|
||||
|
||||
|
||||
#if defined(HAVE_AESGCM) && defined(WOLFSSL_CAAM_AESGCM)
|
||||
int wc_CAAM_AesGcmEncrypt(Aes* aes, const byte* in, byte* out, word32 sz,
|
||||
const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
return wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz, authTag,
|
||||
authTagSz, authIn, authInSz, CAAM_ENC, CAAM_AESGCM);
|
||||
}
|
||||
|
||||
|
||||
int wc_CAAM_AesGcmDecrypt(Aes* aes, const byte* in, byte* out, word32 sz,
|
||||
const byte* nonce, word32 nonceSz, const byte* authTag,
|
||||
word32 authTagSz, const byte* authIn, word32 authInSz)
|
||||
{
|
||||
return wc_CAAM_AesAeadCommon(aes, in, out, sz, nonce, nonceSz,
|
||||
(byte*)authTag, authTagSz, authIn, authInSz, CAAM_DEC, CAAM_AESGCM);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int wc_CAAM_AesCbcCtrCommon(Aes* aes, byte* out, const byte* in,
|
||||
word32 sz, int dir, int mode)
|
||||
{
|
||||
word32 blocks;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
if (blocks > 0) {
|
||||
CAAM_BUFFER buf[5];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
int ret;
|
||||
|
||||
if (wc_AesGetKeySize(aes, &keySz) != 0 && aes->blackKey == 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (CAAM_ADDRESS)(void*)aes->devKey;
|
||||
buf[0].Length = keySz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (CAAM_ADDRESS)aes->reg;
|
||||
buf[1].Length = AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (CAAM_ADDRESS)in;
|
||||
buf[2].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
||||
buf[3].TheAddress = (CAAM_ADDRESS)out;
|
||||
buf[3].Length = blocks * AES_BLOCK_SIZE;
|
||||
|
||||
/* buffer for updated IV */
|
||||
buf[4].BufferType = DataBuffer;
|
||||
buf[4].TheAddress = (CAAM_ADDRESS)aes->reg;
|
||||
buf[4].Length = AES_BLOCK_SIZE;
|
||||
|
||||
arg[0] = dir;
|
||||
arg[1] = keySz;
|
||||
arg[2] = blocks * AES_BLOCK_SIZE;
|
||||
arg[3] = aes->blackKey;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, 5, arg, mode)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES CBC operation");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
/* Increment AES counter (from wolfcrypt/src/aes.c) */
|
||||
static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
|
||||
{
|
||||
/* in network byte order so start at end and work back */
|
||||
int i;
|
||||
for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
|
||||
if (++inOutCtr[i]) /* we're done unless we overflow */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int wc_CAAM_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
byte* tmp;
|
||||
word32 keySz;
|
||||
int ret, blocks;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesGetKeySize(aes, &keySz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* consume any unused bytes left in aes->tmp */
|
||||
tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
|
||||
while (aes->left && sz) {
|
||||
*(out++) = *(in++) ^ *(tmp++);
|
||||
aes->left--;
|
||||
sz--;
|
||||
}
|
||||
|
||||
/* do full blocks to then get potential left over amount */
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
if (blocks > 0) {
|
||||
ret = wc_CAAM_AesCbcCtrCommon(aes, out, in, blocks * AES_BLOCK_SIZE,
|
||||
CAAM_ENC, CAAM_AESCTR);
|
||||
|
||||
out += blocks * AES_BLOCK_SIZE;
|
||||
in += blocks * AES_BLOCK_SIZE;
|
||||
sz -= blocks * AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (sz) {
|
||||
if ((ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg))
|
||||
!= 0) {
|
||||
return ret;
|
||||
}
|
||||
IncrementAesCounter((byte*)aes->reg);
|
||||
|
||||
aes->left = AES_BLOCK_SIZE;
|
||||
tmp = (byte*)aes->tmp;
|
||||
|
||||
while (sz--) {
|
||||
*(out++) = *(in++) ^ *(tmp++);
|
||||
aes->left--;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
|
||||
int wc_CAAM_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
return wc_CAAM_AesCbcCtrCommon(aes, out, in, sz, CAAM_ENC, CAAM_AESCBC);
|
||||
}
|
||||
|
||||
|
||||
int wc_CAAM_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
return wc_CAAM_AesCbcCtrCommon(aes, out, in, sz, CAAM_DEC, CAAM_AESCBC);
|
||||
}
|
||||
|
||||
#if defined(HAVE_AES_ECB)
|
||||
static int wc_CAAM_AesEcbCommon(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
int dir)
|
||||
{
|
||||
word32 blocks;
|
||||
CAAM_BUFFER buf[4];
|
||||
word32 arg[4];
|
||||
word32 keySz = 0;
|
||||
int ret;
|
||||
int idx = 0;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
if (wc_AesGetKeySize(aes, &keySz) != 0 && aes->blackKey == 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)aes->devKey;
|
||||
buf[idx].Length = keySz;
|
||||
idx++;
|
||||
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)in;
|
||||
buf[idx].Length = blocks * AES_BLOCK_SIZE;
|
||||
idx++;
|
||||
|
||||
buf[idx].BufferType = DataBuffer | LastBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)out;
|
||||
buf[idx].Length = blocks * AES_BLOCK_SIZE;
|
||||
idx++;
|
||||
|
||||
arg[0] = dir;
|
||||
arg[1] = keySz;
|
||||
arg[2] = blocks * AES_BLOCK_SIZE;
|
||||
arg[3] = aes->blackKey;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, idx, arg, CAAM_AESECB)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES ECB encrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* is assumed that input size is a multiple of AES_BLOCK_SIZE */
|
||||
int wc_CAAM_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
return wc_CAAM_AesEcbCommon(aes, out, in, sz, CAAM_ENC);
|
||||
}
|
||||
|
||||
|
||||
int wc_CAAM_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
return wc_CAAM_AesEcbCommon(aes, out, in, sz, CAAM_DEC);
|
||||
}
|
||||
#endif /* HAVE_AES_ECB */
|
||||
#endif /* WOLFSSL_CAAM && !NO_AES */
|
@ -0,0 +1,205 @@
|
||||
/* wolfcaam_cmac.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>
|
||||
|
||||
#if defined(WOLFSSL_CAAM) && defined(WOLFSSL_CMAC) && defined(WOLFSSL_CAAM_CMAC)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h>
|
||||
|
||||
/* returns 0 on success */
|
||||
int wc_CAAM_Cmac(Cmac* cmac, const byte* key, word32 keySz, const byte* in,
|
||||
word32 inSz, byte* out, word32* outSz, int type, void* ctx)
|
||||
{
|
||||
word32 args[4] = {0};
|
||||
CAAM_BUFFER buf[9];
|
||||
word32 idx = 0;
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
int ret;
|
||||
int blocks = 0;
|
||||
|
||||
byte* pt = (byte*)in;
|
||||
int sz = inSz;
|
||||
(void)type;
|
||||
|
||||
args[0] = 0;
|
||||
if (outSz != NULL && *outSz > 16) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (out != NULL && outSz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (key != NULL || ctx != NULL) {
|
||||
XMEMSET(&cmac->aes, 0, sizeof(Aes));
|
||||
if (cmac->blackKey == 0) {
|
||||
if (ctx != NULL) {
|
||||
cmac->blackKey = 1;
|
||||
XMEMCPY((byte*)cmac->aes.key, (byte*)ctx, keySz + 16);
|
||||
}
|
||||
else {
|
||||
XMEMCPY((byte*)cmac->aes.key, (byte*)key, keySz);
|
||||
}
|
||||
}
|
||||
cmac->keylen = keySz;
|
||||
cmac->initialized = 0;
|
||||
cmac->bufferSz = 0;
|
||||
XMEMSET(cmac->buffer, 0, AES_BLOCK_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)cmac->aes.key;
|
||||
buf[idx].Length = cmac->keylen;
|
||||
idx++;
|
||||
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)cmac->ctx;
|
||||
buf[idx].Length = sizeof(cmac->ctx);
|
||||
idx++;
|
||||
|
||||
if (in != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
if (wc_CMAC_Grow(cmac, in, inSz) != 0) {
|
||||
WOLFSSL_MSG("Error growing CMAC buffer");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
args[0] |= CAAM_ALG_UPDATE;
|
||||
|
||||
/* first take care of any left overs */
|
||||
if (cmac->bufferSz > 0) {
|
||||
word32 add;
|
||||
|
||||
if (cmac->bufferSz > AES_BLOCK_SIZE) {
|
||||
WOLFSSL_MSG("Error with CMAC buffer size");
|
||||
return -1;
|
||||
}
|
||||
add = (sz < ((int)(AES_BLOCK_SIZE - cmac->bufferSz))) ? sz :
|
||||
(int)(AES_BLOCK_SIZE - cmac->bufferSz);
|
||||
XMEMCPY(&cmac->buffer[cmac->bufferSz], pt, add);
|
||||
|
||||
cmac->bufferSz += add;
|
||||
pt += add;
|
||||
sz -= add;
|
||||
}
|
||||
|
||||
/* flash out temporary storage for block size if full and more data
|
||||
* is coming, otherwise hold it until final operation */
|
||||
if (cmac->bufferSz == AES_BLOCK_SIZE && (sz > 0)) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)scratch;
|
||||
buf[idx].Length = cmac->bufferSz;
|
||||
idx++;
|
||||
blocks++;
|
||||
cmac->bufferSz = 0;
|
||||
XMEMCPY(scratch, (byte*)cmac->buffer, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* In order to trigger read of CTX state there needs to be some data
|
||||
* saved until final call */
|
||||
if ((sz >= AES_BLOCK_SIZE) && (sz % AES_BLOCK_SIZE == 0)) {
|
||||
|
||||
if (cmac->bufferSz > 0) {
|
||||
/* this case should never be hit */
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMCPY(&cmac->buffer[0], pt + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||
cmac->bufferSz = AES_BLOCK_SIZE;
|
||||
sz -= AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (sz >= AES_BLOCK_SIZE) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)pt;
|
||||
buf[idx].Length = sz - (sz % AES_BLOCK_SIZE);
|
||||
blocks += sz / AES_BLOCK_SIZE;
|
||||
sz -= buf[idx].Length;
|
||||
pt += buf[idx].Length;
|
||||
idx++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (out != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
if (cmac->msg != NULL) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)cmac->msg;
|
||||
buf[idx].Length = cmac->used;
|
||||
idx++;
|
||||
}
|
||||
#else
|
||||
/* handle any leftovers */
|
||||
if (cmac->bufferSz > 0) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)cmac->buffer;
|
||||
buf[idx].Length = cmac->bufferSz;
|
||||
idx++;
|
||||
}
|
||||
#endif
|
||||
args[0] |= CAAM_ALG_FINAL;
|
||||
blocks++; /* always run on final call */
|
||||
}
|
||||
|
||||
/* set key size */
|
||||
args[1] = cmac->keylen;
|
||||
args[2] = cmac->blackKey;
|
||||
|
||||
/* only call down to CAAM if we have a full block to do or is final */
|
||||
if (blocks > 0) {
|
||||
if (cmac->initialized == 0) {
|
||||
args[0] |= CAAM_ALG_INIT;
|
||||
cmac->initialized = 1;
|
||||
}
|
||||
|
||||
ret = wc_caamAddAndWait(buf, idx, args, CAAM_CMAC);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (out != NULL) {
|
||||
XMEMCPY(out, cmac->ctx, *outSz);
|
||||
}
|
||||
|
||||
/* store leftovers */
|
||||
if (sz > 0) {
|
||||
word32 add = (sz < (int)(AES_BLOCK_SIZE - cmac->bufferSz))?
|
||||
(word32)sz :
|
||||
(AES_BLOCK_SIZE - cmac->bufferSz);
|
||||
|
||||
if (pt == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMCPY(&cmac->buffer[cmac->bufferSz], pt, add);
|
||||
cmac->bufferSz += add;
|
||||
}
|
||||
|
||||
(void)scratch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_CAAM && WOLFSSL_CMAC */
|
||||
|
@ -0,0 +1,770 @@
|
||||
/* wolfcaam_ecdsa.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>
|
||||
|
||||
#if defined(WOLFSSL_CAAM) && defined(HAVE_ECC) && defined(WOLFSSL_CAAM_ECC)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/coding.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
|
||||
/* FIPS build has replaced ecc.h. */
|
||||
#define wc_ecc_key_get_priv(key) (&((key)->k))
|
||||
#define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_DEVCRYPTO_ECDSA)
|
||||
/* offload calls through devcrypto support */
|
||||
|
||||
|
||||
/* create signature using CAAM
|
||||
* returns MP_OKAY on success
|
||||
*/
|
||||
static int wc_CAAM_DevEccSign(const byte* in, int inlen, byte* out,
|
||||
word32* outlen, WC_RNG *rng, ecc_key *key)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
int ret, keySz;
|
||||
byte r[MAX_ECC_BYTES] = {0};
|
||||
byte s[MAX_ECC_BYTES] = {0};
|
||||
|
||||
byte pk[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
|
||||
|
||||
(void)rng;
|
||||
if (key->dp != NULL) {
|
||||
dp = key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(key->idx);
|
||||
}
|
||||
|
||||
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
|
||||
WOLFSSL_MSG("Limiting CAAM to P256 and P384 for now");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
keySz = wc_ecc_size(key);
|
||||
|
||||
/* private key */
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(key), pk, keySz) != MP_OKAY)
|
||||
{
|
||||
return MP_TO_E;
|
||||
}
|
||||
|
||||
ret = wc_DevCryptoEccSign(dp->id, key->blackKey, pk, keySz, in, inlen,
|
||||
r, keySz, s, keySz);
|
||||
|
||||
/* convert signature from raw bytes to signature format */
|
||||
if (ret == 0) {
|
||||
mp_int mpr, mps;
|
||||
|
||||
mp_init(&mpr);
|
||||
mp_init(&mps);
|
||||
|
||||
mp_read_unsigned_bin(&mpr, r, keySz);
|
||||
mp_read_unsigned_bin(&mps, s, keySz);
|
||||
|
||||
ret = StoreECC_DSA_Sig(out, outlen, &mpr, &mps);
|
||||
mp_free(&mpr);
|
||||
mp_free(&mps);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Issue converting to signature\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* verify with individual r and s signature parts
|
||||
* returns MP_OKAY on success and sets 'res' to 1 if verified
|
||||
*/
|
||||
static int wc_CAAM_DevEccVerify_ex(mp_int* r, mp_int *s, const byte* hash,
|
||||
word32 hashlen, int* res, ecc_key* key)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
int ret;
|
||||
int keySz;
|
||||
|
||||
byte rbuf[MAX_ECC_BYTES] = {0};
|
||||
byte sbuf[MAX_ECC_BYTES] = {0};
|
||||
|
||||
byte qx[MAX_ECC_BYTES] = {0};
|
||||
byte qy[MAX_ECC_BYTES] = {0};
|
||||
byte qxy[MAX_ECC_BYTES * 2] = {0};
|
||||
word32 qxLen, qyLen;
|
||||
|
||||
if (key->dp != NULL) {
|
||||
dp = key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(key->idx);
|
||||
}
|
||||
|
||||
/* Wx,y public key */
|
||||
keySz = wc_ecc_size(key);
|
||||
qxLen = qyLen = MAX_ECC_BYTES;
|
||||
wc_ecc_export_public_raw(key, qx, &qxLen, qy, &qyLen);
|
||||
XMEMCPY(qxy, qx, qxLen);
|
||||
XMEMCPY(qxy+qxLen, qy, qyLen);
|
||||
|
||||
if (mp_to_unsigned_bin_len(r, rbuf, keySz) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
if (mp_to_unsigned_bin_len(s, sbuf, keySz) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
ret = wc_DevCryptoEccVerify(dp->id, qxy, qxLen + qyLen, hash, hashlen,
|
||||
rbuf, keySz, sbuf, keySz);
|
||||
|
||||
*res = 0;
|
||||
if (ret == 0)
|
||||
*res = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Does ECDH operation using CAAM and returns MP_OKAY on success */
|
||||
static int wc_CAAM_DevEcdh(ecc_key* private_key, ecc_key* public_key, byte* out,
|
||||
word32* outlen)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
int ret, keySz;
|
||||
|
||||
byte pk[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
|
||||
byte qx[MAX_ECC_BYTES] = {0};
|
||||
byte qy[MAX_ECC_BYTES] = {0};
|
||||
byte qxy[MAX_ECC_BYTES * 2] = {0};
|
||||
word32 qxSz, qySz;
|
||||
|
||||
if (private_key->dp != NULL) {
|
||||
dp = private_key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(private_key->idx);
|
||||
}
|
||||
|
||||
keySz = wc_ecc_size(private_key);
|
||||
if (*outlen < (word32)keySz) {
|
||||
WOLFSSL_MSG("out buffer is to small");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* public key */
|
||||
qxSz = qySz = MAX_ECC_BYTES;
|
||||
wc_ecc_export_public_raw(public_key, qx, &qxSz, qy, &qySz);
|
||||
XMEMCPY(qxy, qx, qxSz);
|
||||
XMEMCPY(qxy+qxSz, qy, qySz);
|
||||
|
||||
/* private key */
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(private_key), pk, keySz) !=
|
||||
MP_OKAY) {
|
||||
WOLFSSL_MSG("error getting private key buffer");
|
||||
return MP_TO_E;
|
||||
}
|
||||
|
||||
ret = wc_DevCryptoEccEcdh(dp->id, private_key->blackKey, pk, keySz,
|
||||
qxy, qxSz + qySz, out, *outlen);
|
||||
if (ret == 0) {
|
||||
*outlen = keySz;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
/* [ private black key ] [ x , y ] */
|
||||
static int wc_CAAM_DevMakeEccKey(WC_RNG* rng, int keySize, ecc_key* key,
|
||||
int curveId)
|
||||
{
|
||||
int ret;
|
||||
int blackKey = 1; /* default to using black encrypted keys */
|
||||
|
||||
byte s[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
|
||||
byte xy[MAX_ECC_BYTES*2] = {0};
|
||||
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
|
||||
/* if set to default curve then assume SECP256R1 */
|
||||
if (keySize == 32 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP256R1;
|
||||
|
||||
if (curveId != ECC_SECP256R1 &&
|
||||
curveId != ECC_SECP384R1) {
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
ret = wc_DevCryptoEccKeyGen(curveId, blackKey, s, keySize, xy, keySize*2);
|
||||
if (wc_ecc_import_unsigned(key, xy, xy + keySize, s, curveId) != 0) {
|
||||
WOLFSSL_MSG("issue importing key");
|
||||
return -1;
|
||||
}
|
||||
key->blackKey = blackKey;
|
||||
|
||||
(void)rng;
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_KEY_GEN */
|
||||
|
||||
#endif /* WOLFSSL_DEVCRYPTO_ECDSA */
|
||||
|
||||
#ifndef WOLFSSL_IMXRT1170_CAAM
|
||||
/* helper function get the ECDSEL value, this is a value that signals the
|
||||
* hardware to use preloaded curve parameters
|
||||
*/
|
||||
static word32 GetECDSEL(int curveId, word32 PD_BIT)
|
||||
{
|
||||
word32 ecdsel = 0;
|
||||
|
||||
switch (curveId) {
|
||||
case ECC_SECP192R1:
|
||||
ecdsel = (PD_BIT | CAAM_ECDSA_P192);
|
||||
break;
|
||||
|
||||
case ECC_SECP224R1:
|
||||
ecdsel = (PD_BIT | CAAM_ECDSA_P224);
|
||||
break;
|
||||
|
||||
case ECC_CURVE_DEF:
|
||||
case ECC_SECP256R1:
|
||||
ecdsel = (PD_BIT | CAAM_ECDSA_P256);
|
||||
break;
|
||||
|
||||
case ECC_SECP384R1:
|
||||
ecdsel = (PD_BIT | CAAM_ECDSA_P384);
|
||||
break;
|
||||
|
||||
case ECC_SECP521R1:
|
||||
ecdsel = (PD_BIT | CAAM_ECDSA_P521);
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("not using preset curve parameters");
|
||||
}
|
||||
|
||||
return ecdsel;
|
||||
}
|
||||
|
||||
|
||||
/* create signature using CAAM
|
||||
* returns MP_OKAY on success
|
||||
*/
|
||||
int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen,
|
||||
WC_RNG *rng, ecc_key *key, int devId)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
word32 args[4] = {0};
|
||||
CAAM_BUFFER buf[9];
|
||||
int ret, keySz;
|
||||
word32 ecdsel = 0;
|
||||
byte r[MAX_ECC_BYTES] = {0};
|
||||
byte s[MAX_ECC_BYTES] = {0};
|
||||
word32 idx = 0;
|
||||
byte pk[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
|
||||
|
||||
#if defined(WOLFSSL_DEVCRYPTO_ECDSA)
|
||||
if (devId == WOLFSSL_CAAM_DEVID) {
|
||||
return wc_CAAM_DevEccSign(in, inlen, out, outlen, rng, key);
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)rng;
|
||||
if (key->dp != NULL) {
|
||||
dp = key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(key->idx);
|
||||
}
|
||||
|
||||
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
|
||||
WOLFSSL_MSG("Limiting CAAM to P256/P384 for now");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* check for known predetermined parameters */
|
||||
ecdsel = GetECDSEL(dp->id, CAAM_ECDSA_PD);
|
||||
if (ecdsel == 0) {
|
||||
WOLFSSL_MSG("Unsupported curve type");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
keySz = wc_ecc_size(key);
|
||||
|
||||
/* private key */
|
||||
if (key->blackKey == CAAM_BLACK_KEY_SM) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)key->blackKey;
|
||||
args[0] = CAAM_BLACK_KEY_SM; /* is a black key in sm */
|
||||
buf[idx].Length = keySz;
|
||||
}
|
||||
else {
|
||||
if (key->blackKey == CAAM_BLACK_KEY_CCM) {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(key), pk,
|
||||
keySz + WC_CAAM_MAC_SZ) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
buf[idx].Length = keySz + WC_CAAM_MAC_SZ;
|
||||
}
|
||||
else {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(key), pk, keySz) !=
|
||||
MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
buf[idx].Length = keySz;
|
||||
}
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)pk;
|
||||
args[0] = key->blackKey; /* potential black key, not in sm */
|
||||
}
|
||||
idx++;
|
||||
|
||||
/* hash to sign */
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)in;
|
||||
buf[idx].Length = inlen;
|
||||
idx++;
|
||||
|
||||
/* r output */
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)r;
|
||||
buf[idx].Length = keySz;
|
||||
idx++;
|
||||
|
||||
/* s output */
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)s;
|
||||
buf[idx].Length = keySz;
|
||||
idx++;
|
||||
|
||||
args[1] = ecdsel;
|
||||
args[2] = inlen;
|
||||
args[3] = keySz;
|
||||
|
||||
ret = wc_caamAddAndWait(buf, idx, args, CAAM_ECDSA_SIGN);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
/* convert signature from raw bytes to signature format */
|
||||
{
|
||||
mp_int mpr, mps;
|
||||
|
||||
mp_init(&mpr);
|
||||
mp_init(&mps);
|
||||
|
||||
mp_read_unsigned_bin(&mpr, r, keySz);
|
||||
mp_read_unsigned_bin(&mps, s, keySz);
|
||||
|
||||
ret = StoreECC_DSA_Sig(out, outlen, &mpr, &mps);
|
||||
mp_free(&mpr);
|
||||
mp_free(&mps);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Issue converting to signature");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
(void)devId;
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
|
||||
/* verify with individual r and s signature parts
|
||||
* returns MP_OKAY on success and sets 'res' to 1 if verified
|
||||
*/
|
||||
static int wc_CAAM_EccVerify_ex(mp_int* r, mp_int *s, const byte* hash,
|
||||
word32 hashlen, int* res, ecc_key* key)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
word32 args[4] = {0};
|
||||
CAAM_BUFFER buf[9];
|
||||
int ret;
|
||||
int keySz;
|
||||
word32 idx = 0;
|
||||
word32 ecdsel = 0;
|
||||
|
||||
byte rbuf[MAX_ECC_BYTES] = {0};
|
||||
byte sbuf[MAX_ECC_BYTES] = {0};
|
||||
|
||||
byte qx[MAX_ECC_BYTES] = {0};
|
||||
byte qy[MAX_ECC_BYTES] = {0};
|
||||
byte qxy[MAX_ECC_BYTES * 2] = {0};
|
||||
byte tmp[MAX_ECC_BYTES * 2] = {0};
|
||||
word32 qxLen, qyLen;
|
||||
|
||||
if (key->dp != NULL) {
|
||||
dp = key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(key->idx);
|
||||
}
|
||||
|
||||
/* right now only support P256/P384 @TODO */
|
||||
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
|
||||
WOLFSSL_MSG("Only support P256 and P384 verify with CAAM for now");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* check for known predetermined parameters */
|
||||
ecdsel = GetECDSEL(dp->id, CAAM_ECDSA_PD);
|
||||
|
||||
if (ecdsel == 0) {
|
||||
WOLFSSL_MSG("Curve parameters not supported");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* Wx,y public key */
|
||||
keySz = wc_ecc_size(key);
|
||||
if (key->securePubKey > 0) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)key->securePubKey;
|
||||
buf[idx].Length = keySz * 2;
|
||||
args[0] = 1; /* using public key in secure memory */
|
||||
}
|
||||
else {
|
||||
qxLen = qyLen = MAX_ECC_BYTES;
|
||||
wc_ecc_export_public_raw(key, qx, &qxLen, qy, &qyLen);
|
||||
XMEMCPY(qxy, qx, qxLen);
|
||||
XMEMCPY(qxy+qxLen, qy, qyLen);
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)qxy;
|
||||
buf[idx].Length = qxLen + qyLen;
|
||||
}
|
||||
idx++;
|
||||
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)hash;
|
||||
buf[idx].Length = hashlen;
|
||||
idx++;
|
||||
|
||||
if (mp_to_unsigned_bin_len(r, rbuf, keySz) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)rbuf;
|
||||
buf[idx].Length = keySz;
|
||||
idx++;
|
||||
|
||||
if (mp_to_unsigned_bin_len(s, sbuf, keySz) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)sbuf;
|
||||
buf[idx].Length = keySz;
|
||||
idx++;
|
||||
|
||||
/* temporary scratch buffer, the manual calls for it and HW expects it */
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)tmp;
|
||||
buf[idx].Length = sizeof(tmp);
|
||||
idx++;
|
||||
|
||||
args[1] = ecdsel;
|
||||
args[2] = hashlen;
|
||||
args[3] = wc_ecc_size(key);
|
||||
ret = wc_caamAddAndWait(buf, idx, args, CAAM_ECDSA_VERIFY);
|
||||
|
||||
*res = 0;
|
||||
if (ret == 0)
|
||||
*res = 1;
|
||||
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
|
||||
/* Verify with ASN1 syntax around the signature
|
||||
* returns MP_OKAY on success
|
||||
*/
|
||||
int wc_CAAM_EccVerify(const byte* sig, word32 siglen, const byte* hash,
|
||||
word32 hashlen, int* res, ecc_key* key, int devId)
|
||||
{
|
||||
int ret;
|
||||
mp_int r, s;
|
||||
|
||||
ret = DecodeECC_DSA_Sig(sig, siglen, &r, &s);
|
||||
if (ret == 0) {
|
||||
#if defined(WOLFSSL_DEVCRYPTO_ECDSA)
|
||||
if (devId == WOLFSSL_CAAM_DEVID) {
|
||||
ret = wc_CAAM_DevEccVerify_ex(&r, &s, hash, hashlen, res, key);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = wc_CAAM_EccVerify_ex(&r, &s, hash, hashlen, res, key);
|
||||
}
|
||||
mp_free(&r);
|
||||
mp_free(&s);
|
||||
}
|
||||
|
||||
(void)devId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Does ECDH operation using CAAM and returns MP_OKAY on success */
|
||||
int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out,
|
||||
word32* outlen, int devId)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
word32 args[4] = {0};
|
||||
CAAM_BUFFER buf[9];
|
||||
int ret, keySz;
|
||||
word32 ecdsel = 0; /* ecc parameters in hardware */
|
||||
word32 idx = 0;
|
||||
|
||||
byte pk[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
|
||||
byte qx[MAX_ECC_BYTES] = {0};
|
||||
byte qy[MAX_ECC_BYTES] = {0};
|
||||
byte qxy[MAX_ECC_BYTES * 2] = {0};
|
||||
word32 qxSz, qySz;
|
||||
|
||||
#if defined(WOLFSSL_DEVCRYPTO_ECDSA)
|
||||
if (devId == WOLFSSL_CAAM_DEVID) {
|
||||
return wc_CAAM_DevEcdh(private_key, public_key, out, outlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (private_key->dp != NULL) {
|
||||
dp = private_key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(private_key->idx);
|
||||
}
|
||||
|
||||
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* check for known predetermined parameters */
|
||||
ecdsel = GetECDSEL(dp->id, CAAM_ECDSA_KEYGEN_PD);
|
||||
if (ecdsel == 0) { /* predefined value not known, loading all parameters */
|
||||
WOLFSSL_MSG("Unsupported curve parameters");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
keySz = wc_ecc_size(private_key);
|
||||
if (*outlen < (word32)keySz) {
|
||||
WOLFSSL_MSG("out buffer is to small");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* public key */
|
||||
if (public_key->securePubKey > 0) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)public_key->securePubKey;
|
||||
buf[idx].Length = keySz * 2;
|
||||
args[1] = 1; /* using public key with secure memory address */
|
||||
}
|
||||
else {
|
||||
qxSz = qySz = MAX_ECC_BYTES;
|
||||
wc_ecc_export_public_raw(public_key, qx, &qxSz, qy, &qySz);
|
||||
XMEMCPY(qxy, qx, qxSz);
|
||||
XMEMCPY(qxy+qxSz, qy, qySz);
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)qxy;
|
||||
buf[idx].Length = qxSz + qySz;
|
||||
}
|
||||
idx++;
|
||||
|
||||
/* private key */
|
||||
if (private_key->blackKey > 0 &&
|
||||
(private_key->blackKey != CAAM_BLACK_KEY_CCM &&
|
||||
private_key->blackKey != CAAM_BLACK_KEY_ECB)) {
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)private_key->blackKey;
|
||||
args[0] = CAAM_BLACK_KEY_SM; /* is a black key */
|
||||
buf[idx].Length = sizeof(unsigned int);
|
||||
}
|
||||
else {
|
||||
if (keySz > MAX_ECC_BYTES) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (private_key->blackKey == CAAM_BLACK_KEY_CCM) {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(private_key), pk,
|
||||
keySz + WC_CAAM_MAC_SZ) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
buf[idx].Length = keySz + WC_CAAM_MAC_SZ;
|
||||
}
|
||||
else {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(private_key), pk,
|
||||
keySz) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
buf[idx].Length = keySz;
|
||||
}
|
||||
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)pk;
|
||||
args[0] = private_key->blackKey; /* potential black key, but not sm */
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
int z;
|
||||
unsigned char* pt = (unsigned char*)buf[idx].TheAddress;
|
||||
printf("sending private key [%d] :", buf[idx].Length);
|
||||
for (z = 0; z < buf[idx].Length; z++)
|
||||
printf("%02X", pt[z]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
idx++;
|
||||
|
||||
/* output shared secret */
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)out;
|
||||
buf[idx].Length = keySz;
|
||||
idx++;
|
||||
|
||||
args[2] = ecdsel;
|
||||
args[3] = keySz;
|
||||
ret = wc_caamAddAndWait(buf, idx, args, CAAM_ECDSA_ECDH);
|
||||
(void)devId;
|
||||
if (ret == 0) {
|
||||
*outlen = keySz;
|
||||
return MP_OKAY;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
/* [ private black key ] [ x , y ] */
|
||||
int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId,
|
||||
int devId)
|
||||
{
|
||||
word32 args[4] = {0};
|
||||
CAAM_BUFFER buf[2] = {0};
|
||||
word32 ecdsel = 0;
|
||||
|
||||
int ret;
|
||||
|
||||
byte s[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
|
||||
byte xy[MAX_ECC_BYTES*2] = {0};
|
||||
|
||||
#if defined(WOLFSSL_DEVCRYPTO_ECDSA)
|
||||
if (devId == WOLFSSL_CAAM_DEVID) {
|
||||
return wc_CAAM_DevMakeEccKey(rng, keySize, key, curveId);
|
||||
}
|
||||
#endif
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
|
||||
/* if set to default curve then assume SECP256R1 */
|
||||
if (keySize == 32 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP256R1;
|
||||
if (keySize == 48 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP384R1;
|
||||
|
||||
if (curveId != ECC_SECP256R1 && curveId != ECC_SECP384R1) {
|
||||
/* currently only implemented P256/P384 support */
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
ecdsel = GetECDSEL(curveId, CAAM_ECDSA_KEYGEN_PD);
|
||||
if (ecdsel == 0) {
|
||||
WOLFSSL_MSG("unknown key type or size");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
(void)rng;
|
||||
(void)devId;
|
||||
|
||||
if (key->blackKey == 0) {
|
||||
#ifdef WOLFSSL_CAAM_NO_BLACK_KEY
|
||||
args[0] = 0;
|
||||
#elif defined(WOLFSSL_CAAM_BLACK_KEY_AESCCM)
|
||||
args[0] = CAAM_BLACK_KEY_CCM;
|
||||
#elif defined(WOLFSSL_CAAM_BLACK_KEY_SM)
|
||||
args[0] = CAAM_BLACK_KEY_SM;
|
||||
#else
|
||||
args[0] = CAAM_BLACK_KEY_ECB;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* type of black key was already set in the ecc key struct */
|
||||
args[0] = key->blackKey;
|
||||
}
|
||||
|
||||
args[1] = ecdsel;
|
||||
args[3] = keySize;
|
||||
|
||||
buf[0].TheAddress = (CAAM_ADDRESS)s;
|
||||
if (args[0] == CAAM_BLACK_KEY_SM) {
|
||||
/* only get a physical address */
|
||||
buf[0].Length = sizeof(unsigned int);
|
||||
}
|
||||
else if (args[0] == CAAM_BLACK_KEY_CCM) {
|
||||
/* account for additional MAC */
|
||||
buf[0].Length = keySize + WC_CAAM_MAC_SZ;
|
||||
}
|
||||
else {
|
||||
buf[0].Length = keySize;
|
||||
}
|
||||
buf[1].TheAddress = (CAAM_ADDRESS)xy;
|
||||
buf[1].Length = keySize*2;
|
||||
key->blackKey = args[0];
|
||||
|
||||
ret = wc_caamAddAndWait(buf, 2, args, CAAM_ECDSA_KEYPAIR);
|
||||
if (args[0] == CAAM_BLACK_KEY_SM && ret == 0) {
|
||||
unsigned char* pt = (unsigned char*)buf[0].TheAddress;
|
||||
key->blackKey = (pt[0] << 24) | (pt[1] << 16) | (pt[2] << 8) | pt[3];
|
||||
if (wc_ecc_import_unsigned(key, xy, xy + keySize, NULL, curveId) != 0) {
|
||||
WOLFSSL_MSG("issue importing public key");
|
||||
return -1;
|
||||
}
|
||||
key->partNum = args[2];
|
||||
return MP_OKAY;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
if (wc_ecc_import_unsigned(key, xy, xy + keySize,
|
||||
s, curveId) != 0) {
|
||||
WOLFSSL_MSG("issue importing key");
|
||||
return -1;
|
||||
}
|
||||
key->blackKey = args[0];
|
||||
return MP_OKAY;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif /* WOLFSSL_KEY_GEN */
|
||||
#endif /* WOLFSSL_IMXRT1170_CAAM */
|
||||
|
||||
/* if dealing with a black encrypted key then it can not be checked */
|
||||
int wc_CAAM_EccCheckPrivKey(ecc_key* key, const byte* pubKey, word32 pubKeySz) {
|
||||
(void)pubKey;
|
||||
(void)pubKeySz;
|
||||
|
||||
if (key->dp->id == ECC_SECP256R1 && key->blackKey > 0) {
|
||||
return 0;
|
||||
}
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_QNX_CAAM && HAVE_ECC */
|
@ -0,0 +1,871 @@
|
||||
/* wolfcaam_fsl_nxp.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>
|
||||
|
||||
#if defined(WOLFSSL_IMXRT1170_CAAM)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
|
||||
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
|
||||
/* FIPS build has replaced ecc.h. */
|
||||
#define wc_ecc_key_get_priv(key) (&((key)->k))
|
||||
#define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
|
||||
#endif
|
||||
|
||||
#if defined(FSL_FEATURE_HAS_L1CACHE) || defined(__DCACHE_PRESENT)
|
||||
/* Setup for if memory is cached */
|
||||
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr0);
|
||||
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr1);
|
||||
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr2);
|
||||
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr3);
|
||||
#else
|
||||
/* If not cached */
|
||||
static caam_job_ring_interface_t jr0;
|
||||
static caam_job_ring_interface_t jr1;
|
||||
static caam_job_ring_interface_t jr2;
|
||||
static caam_job_ring_interface_t jr3;
|
||||
#endif
|
||||
|
||||
static wolfSSL_Mutex caamMutex;
|
||||
|
||||
/* Initialize CAAM resources.
|
||||
* return 0 on success */
|
||||
int wc_CAAMInitInterface()
|
||||
{
|
||||
CAAM_Type *base = CAAM;
|
||||
caam_config_t caamConfig;
|
||||
|
||||
if (wc_InitMutex(&caamMutex) != 0) {
|
||||
WOLFSSL_MSG("Could not init mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get default configuration. */
|
||||
CAAM_GetDefaultConfig(&caamConfig);
|
||||
|
||||
/* set the job rings */
|
||||
caamConfig.jobRingInterface[0] = &jr0;
|
||||
caamConfig.jobRingInterface[1] = &jr1;
|
||||
caamConfig.jobRingInterface[2] = &jr2;
|
||||
caamConfig.jobRingInterface[3] = &jr3;
|
||||
|
||||
/* Init CAAM driver, including CAAM's internal RNG */
|
||||
if (CAAM_Init(base, &caamConfig) != kStatus_Success) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* free up CAAM resources */
|
||||
void wc_CAAMFreeInterface()
|
||||
{
|
||||
wc_FreeMutex(&caamMutex);
|
||||
if (CAAM_Deinit(CAAM) != kStatus_Success) {
|
||||
WOLFSSL_MSG("Failed to deinit CAAM!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !defined(NO_SHA) || defined(WOLFSSL_SHA224) || !defined(NO_SHA256) \
|
||||
|| defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
|
||||
/* convert the wolfCrypt hash type to NXP enum */
|
||||
static caam_hash_algo_t WC2NXP(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case WC_HASH_TYPE_SHA:
|
||||
return kCAAM_Sha1;
|
||||
case WC_HASH_TYPE_SHA224:
|
||||
return kCAAM_Sha224;
|
||||
case WC_HASH_TYPE_SHA256:
|
||||
return kCAAM_Sha256;
|
||||
case WC_HASH_TYPE_SHA384:
|
||||
return kCAAM_Sha384;
|
||||
case WC_HASH_TYPE_SHA512:
|
||||
return kCAAM_Sha512;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Common init code for hash algorithms.
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_CAAM_HashInit(caam_handle_t* hndl, caam_hash_ctx_t* ctx, int type)
|
||||
{
|
||||
if (hndl == NULL || ctx == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* only using job ring0 for now */
|
||||
hndl->jobRing = kCAAM_JobRing0;
|
||||
if (CAAM_HASH_Init(CAAM, hndl, ctx, WC2NXP(type), NULL, 0u)
|
||||
!= kStatus_Success) {
|
||||
return WC_HW_E;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* All hashing algorithms have common code except the 'type' to perform.
|
||||
* This helper function implements the common code.
|
||||
* returns 0 on success
|
||||
*/
|
||||
static int wc_CAAM_CommonHash(caam_handle_t* hndl, caam_hash_ctx_t *ctx,
|
||||
const byte* in, int inSz, byte* digest, size_t digestSz, int hashType)
|
||||
{
|
||||
int ret = 0;
|
||||
status_t status;
|
||||
|
||||
if (in != NULL && inSz > 0) {
|
||||
byte *alignedIn = NULL;
|
||||
byte *tmpIn = NULL;
|
||||
|
||||
if ((wc_ptr_t)in % CAAM_BUFFER_ALIGN) {
|
||||
/* input not aligned */
|
||||
tmpIn = (byte*)XMALLOC(inSz + CAAM_BUFFER_ALIGN, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
|
||||
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
|
||||
XMEMCPY(alignedIn, in, inSz);
|
||||
}
|
||||
else {
|
||||
alignedIn = (byte*)in;
|
||||
}
|
||||
|
||||
status = CAAM_HASH_Update(ctx, alignedIn, inSz);
|
||||
if (tmpIn != NULL) {
|
||||
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (status != kStatus_Success) {
|
||||
return WC_HW_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (digest != NULL) {
|
||||
byte *tmpOut = NULL;
|
||||
|
||||
byte *alignedOut = NULL;
|
||||
size_t sz = digestSz;
|
||||
|
||||
if ((wc_ptr_t)digest % CAAM_BUFFER_ALIGN) {
|
||||
/* input not aligned */
|
||||
tmpOut = (byte*)XMALLOC(sz + CAAM_BUFFER_ALIGN, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
alignedOut = tmpOut + (CAAM_BUFFER_ALIGN -
|
||||
((wc_ptr_t)tmpOut % CAAM_BUFFER_ALIGN));
|
||||
}
|
||||
else {
|
||||
alignedOut = digest;
|
||||
}
|
||||
|
||||
status = CAAM_HASH_Finish(ctx, alignedOut, &sz);
|
||||
if (tmpOut != NULL) {
|
||||
XMEMCPY(digest, alignedOut, sz);
|
||||
XFREE(tmpOut, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (status != kStatus_Success) {
|
||||
WOLFSSL_MSG("Failed on CAAM_HASH_Finish");
|
||||
return WC_HW_E;
|
||||
}
|
||||
else {
|
||||
ret = wc_CAAM_HashInit(hndl, ctx, hashType);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(NO_SHA)
|
||||
/* SHA returns 0 on success */
|
||||
int wc_CAAM_ShaHash(wc_Sha* sha, const byte* in, word32 inSz, byte* digest)
|
||||
{
|
||||
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
|
||||
WC_SHA_DIGEST_SIZE, WC_HASH_TYPE_SHA);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA224
|
||||
/* SHA224 returns 0 on success */
|
||||
int wc_CAAM_Sha224Hash(wc_Sha224* sha, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
|
||||
WC_SHA224_DIGEST_SIZE, WC_HASH_TYPE_SHA224);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(NO_SHA256)
|
||||
/* SHA256 returns 0 on success */
|
||||
int wc_CAAM_Sha256Hash(wc_Sha256* sha, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
|
||||
WC_SHA256_DIGEST_SIZE, WC_HASH_TYPE_SHA256);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
/* SHA384 returns 0 on success */
|
||||
int wc_CAAM_Sha384Hash(wc_Sha384* sha, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
|
||||
WC_SHA384_DIGEST_SIZE, WC_HASH_TYPE_SHA384);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
/* SHA512 returns 0 on success */
|
||||
int wc_CAAM_Sha512Hash(wc_Sha512* sha, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
|
||||
WC_SHA512_DIGEST_SIZE, WC_HASH_TYPE_SHA512);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_AES_CBC
|
||||
/* AES-CBC returns 0 on success */
|
||||
static int DoAesCBC(unsigned int args[4], CAAM_BUFFER *buf, int sz)
|
||||
{
|
||||
status_t status;
|
||||
caam_handle_t hndl;
|
||||
|
||||
/* @TODO running on alternate job rings - performance enhancement */
|
||||
hndl.jobRing = kCAAM_JobRing0;
|
||||
|
||||
if (args[0] == CAAM_DEC) {
|
||||
status = CAAM_AES_DecryptCbc(CAAM, &hndl,
|
||||
(const uint8_t*)buf[2].TheAddress, (uint8_t*)buf[3].TheAddress,
|
||||
buf[3].Length, (const uint8_t*)buf[4].TheAddress,
|
||||
(const uint8_t*)buf[0].TheAddress, buf[0].Length);
|
||||
|
||||
/* store updated CBC state */
|
||||
XMEMCPY((byte*)buf[4].TheAddress,
|
||||
(byte*)buf[2].TheAddress + buf[2].Length - AES_BLOCK_SIZE,
|
||||
AES_BLOCK_SIZE);
|
||||
}
|
||||
else {
|
||||
status = CAAM_AES_EncryptCbc(CAAM, &hndl,
|
||||
(const uint8_t*)buf[2].TheAddress, (uint8_t*)buf[3].TheAddress,
|
||||
buf[3].Length, (const uint8_t*)buf[4].TheAddress,
|
||||
(const uint8_t*)buf[0].TheAddress, buf[0].Length);
|
||||
|
||||
/* store updated CBC state */
|
||||
XMEMCPY((byte*)buf[4].TheAddress,
|
||||
(byte*)buf[3].TheAddress + buf[3].Length - AES_BLOCK_SIZE,
|
||||
AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (status != kStatus_Success) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
/* AES-CTR returns 0 on success */
|
||||
static int DoAesCTR(unsigned int args[4], CAAM_BUFFER *buf, int sz)
|
||||
{
|
||||
status_t status;
|
||||
caam_handle_t hndl;
|
||||
byte *tmpIn = NULL;
|
||||
byte *tmpOut = NULL;
|
||||
byte *alignedIn = NULL;
|
||||
byte *alignedOut = NULL;
|
||||
|
||||
if (buf[2].TheAddress % CAAM_BUFFER_ALIGN) {
|
||||
/* input not aligned */
|
||||
tmpIn = (byte*)XMALLOC(buf[2].Length + CAAM_BUFFER_ALIGN, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
|
||||
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
|
||||
XMEMCPY(alignedIn, (byte*)buf[2].TheAddress, buf[2].Length);
|
||||
}
|
||||
else {
|
||||
alignedIn = (byte*)buf[2].TheAddress;
|
||||
}
|
||||
|
||||
if (buf[3].TheAddress % CAAM_BUFFER_ALIGN) {
|
||||
/* output not aligned */
|
||||
tmpOut = (byte*)XMALLOC(buf[3].Length + CAAM_BUFFER_ALIGN, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
alignedOut = tmpOut + (CAAM_BUFFER_ALIGN -
|
||||
((wc_ptr_t)tmpOut % CAAM_BUFFER_ALIGN));
|
||||
}
|
||||
else {
|
||||
alignedOut = (byte*)buf[3].TheAddress;
|
||||
}
|
||||
|
||||
/* @TODO running on alternate job rings - performance enhancement */
|
||||
hndl.jobRing = kCAAM_JobRing0;
|
||||
|
||||
status = CAAM_AES_CryptCtr(CAAM, &hndl, alignedIn, alignedOut,
|
||||
buf[3].Length, (byte*)buf[4].TheAddress, (byte*)buf[0].TheAddress,
|
||||
buf[0].Length, (byte*)buf[2].TheAddress, NULL);
|
||||
if (tmpOut != NULL) {
|
||||
XMEMCPY((byte*)buf[3].TheAddress, alignedOut, buf[3].Length);
|
||||
XFREE(tmpOut, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (tmpIn != NULL) {
|
||||
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (status != kStatus_Success) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_ECC) && defined(WOLFSSL_CAAM_ECC)
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
/* helper function get the ECDSEL value, this is a value that signals the
|
||||
* hardware to use preloaded curve parameters
|
||||
*/
|
||||
static word32 GetECDSEL(int curveId)
|
||||
{
|
||||
word32 ecdsel = 0;
|
||||
|
||||
switch (curveId) {
|
||||
case ECC_SECP192R1:
|
||||
ecdsel = CAAM_ECDSA_P192;
|
||||
break;
|
||||
|
||||
case ECC_SECP224R1:
|
||||
ecdsel = CAAM_ECDSA_P224;
|
||||
break;
|
||||
|
||||
case ECC_CURVE_DEF:
|
||||
case ECC_SECP256R1:
|
||||
ecdsel = CAAM_ECDSA_P256;
|
||||
break;
|
||||
|
||||
case ECC_SECP384R1:
|
||||
ecdsel = CAAM_ECDSA_P384;
|
||||
break;
|
||||
|
||||
case ECC_SECP521R1:
|
||||
ecdsel = CAAM_ECDSA_P521;
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("not using preset curve parameters");
|
||||
}
|
||||
|
||||
return ecdsel;
|
||||
}
|
||||
|
||||
|
||||
/* ECC sign operation on hardware, can handle black keys
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen,
|
||||
WC_RNG *rng, ecc_key *key, int devId)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
int ret = 0;
|
||||
ALIGN16 byte k[MAX_ECC_BYTES + WC_CAAM_MAC_SZ];
|
||||
word32 kSz = MAX_ECC_BYTES + WC_CAAM_MAC_SZ;
|
||||
|
||||
/* input needs to be aligned */
|
||||
byte *alignedIn = NULL;
|
||||
byte *tmpIn = NULL;
|
||||
|
||||
ALIGN16 byte r[MAX_ECC_BYTES] = {0};
|
||||
ALIGN16 byte s[MAX_ECC_BYTES] = {0};
|
||||
word32 rSz = MAX_ECC_BYTES;
|
||||
word32 sSz = MAX_ECC_BYTES;
|
||||
int keySz;
|
||||
word32 ecdsel;
|
||||
word32 enc = 0;
|
||||
status_t status;
|
||||
caam_handle_t hndl;
|
||||
|
||||
/* @TODO running on alternate job rings - performance enhancement */
|
||||
hndl.jobRing = kCAAM_JobRing0;
|
||||
|
||||
(void)rng;
|
||||
if (key->dp != NULL) {
|
||||
dp = key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(key->idx);
|
||||
}
|
||||
|
||||
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
|
||||
WOLFSSL_MSG("Limiting CAAM to P256/P384 for now");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* check for known predetermined parameters */
|
||||
ecdsel = GetECDSEL(dp->id);
|
||||
if (ecdsel == 0) {
|
||||
WOLFSSL_MSG("Unsupported curve type");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
keySz = kSz = wc_ecc_size(key);
|
||||
|
||||
/* private key */
|
||||
if (key->blackKey == CAAM_BLACK_KEY_SM) {
|
||||
ret = -1; /* only handling black keys not SM (secure memory) ones */
|
||||
}
|
||||
else {
|
||||
if (key->blackKey == CAAM_BLACK_KEY_CCM) {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(key), k,
|
||||
kSz + WC_CAAM_MAC_SZ) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(key), k, kSz) !=
|
||||
MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ecdsel = GetECDSEL(dp->id);
|
||||
if (ecdsel == 0) {
|
||||
WOLFSSL_MSG("unknown key type or size");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
switch (key->blackKey) {
|
||||
case 0:
|
||||
enc = 0;
|
||||
break;
|
||||
case CAAM_BLACK_KEY_ECB:
|
||||
enc = CAAM_PKHA_ENC_PRI_AESECB;
|
||||
break;
|
||||
default:
|
||||
WOLFSSL_MSG("unknown/unsupported key type");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((wc_ptr_t)in % CAAM_BUFFER_ALIGN) {
|
||||
/* input not aligned */
|
||||
tmpIn = (byte*)XMALLOC(inlen + CAAM_BUFFER_ALIGN, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
|
||||
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
|
||||
XMEMCPY(alignedIn, in, inlen);
|
||||
}
|
||||
else {
|
||||
alignedIn = (byte*)in;
|
||||
}
|
||||
|
||||
|
||||
status = CAAM_ECC_Sign(CAAM, &hndl, k, kSz, alignedIn, inlen, r, rSz, s,
|
||||
sSz, ecdsel, enc);
|
||||
if (tmpIn != NULL) {
|
||||
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
|
||||
if (status != kStatus_Success) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* convert signature from raw bytes to signature format */
|
||||
if (ret == 0) {
|
||||
mp_int mpr, mps;
|
||||
|
||||
mp_init(&mpr);
|
||||
mp_init(&mps);
|
||||
|
||||
mp_read_unsigned_bin(&mpr, r, keySz);
|
||||
mp_read_unsigned_bin(&mps, s, keySz);
|
||||
|
||||
ret = StoreECC_DSA_Sig(out, outlen, &mpr, &mps);
|
||||
mp_free(&mpr);
|
||||
mp_free(&mps);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Issue converting to signature");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* helper function to handle r/s with verify
|
||||
* returns 0 on success
|
||||
*/
|
||||
static int wc_CAAM_EccVerify_ex(mp_int* r, mp_int *s, const byte* hash,
|
||||
word32 hashlen, int* res, ecc_key* key)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
int keySz;
|
||||
word32 ecdsel = 0;
|
||||
|
||||
/* input needs to be aligned */
|
||||
byte *alignedIn = NULL;
|
||||
byte *tmpIn = NULL;
|
||||
|
||||
ALIGN16 byte rbuf[MAX_ECC_BYTES] = {0};
|
||||
ALIGN16 byte sbuf[MAX_ECC_BYTES] = {0};
|
||||
|
||||
ALIGN16 byte qx[MAX_ECC_BYTES] = {0};
|
||||
ALIGN16 byte qy[MAX_ECC_BYTES] = {0};
|
||||
ALIGN16 byte qxy[MAX_ECC_BYTES * 2] = {0};
|
||||
word32 qxLen, qyLen;
|
||||
|
||||
status_t status;
|
||||
caam_handle_t hndl;
|
||||
|
||||
/* @TODO running on alternate job rings - performance enhancement */
|
||||
hndl.jobRing = kCAAM_JobRing0;
|
||||
|
||||
if (key->dp != NULL) {
|
||||
dp = key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(key->idx);
|
||||
}
|
||||
|
||||
/* right now only support P256/P384 @TODO */
|
||||
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
|
||||
WOLFSSL_MSG("Only support P256 and P384 verify with CAAM for now");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* check for known predetermined parameters */
|
||||
ecdsel = GetECDSEL(dp->id);
|
||||
|
||||
if (ecdsel == 0) {
|
||||
WOLFSSL_MSG("Curve parameters not supported");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* Wx,y public key */
|
||||
keySz = wc_ecc_size(key);
|
||||
qxLen = qyLen = MAX_ECC_BYTES;
|
||||
|
||||
if (wc_ecc_export_public_raw(key, qx, &qxLen, qy, &qyLen) != 0) {
|
||||
WOLFSSL_MSG("Issue exporting public key part");
|
||||
return -1;
|
||||
}
|
||||
XMEMCPY(qxy, qx, qxLen);
|
||||
XMEMCPY(qxy+qxLen, qy, qyLen);
|
||||
|
||||
if (mp_to_unsigned_bin_len(r, rbuf, keySz) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
|
||||
if (mp_to_unsigned_bin_len(s, sbuf, keySz) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
|
||||
if ((wc_ptr_t)hash % CAAM_BUFFER_ALIGN) {
|
||||
/* input not aligned */
|
||||
tmpIn = (byte*)XMALLOC(hashlen + CAAM_BUFFER_ALIGN, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
|
||||
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
|
||||
XMEMCPY(alignedIn, hash, hashlen);
|
||||
}
|
||||
else {
|
||||
alignedIn = (byte*)hash;
|
||||
}
|
||||
|
||||
status = CAAM_ECC_Verify(CAAM, &hndl, qxy, qxLen+qyLen, rbuf,
|
||||
keySz, sbuf, keySz, alignedIn, hashlen, ecdsel);
|
||||
if (tmpIn != NULL) {
|
||||
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
*res = 0;
|
||||
if (status == kStatus_Success) {
|
||||
*res = 1;
|
||||
}
|
||||
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
|
||||
/* ECC verify operation using hardware
|
||||
* returns 0 on success, and sets "res" with verify result (1 for verify ok)
|
||||
*/
|
||||
int wc_CAAM_EccVerify(const byte* sig, word32 siglen, const byte* hash,
|
||||
word32 hashlen, int* res, ecc_key* key, int devId)
|
||||
{
|
||||
int ret;
|
||||
mp_int r, s;
|
||||
|
||||
ret = DecodeECC_DSA_Sig(sig, siglen, &r, &s);
|
||||
if (ret == 0) {
|
||||
ret = wc_CAAM_EccVerify_ex(&r, &s, hash, hashlen, res, key);
|
||||
mp_free(&r);
|
||||
mp_free(&s);
|
||||
}
|
||||
|
||||
(void)devId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ECDH operation using hardware, can handle black keys
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out,
|
||||
word32* outlen, int devId)
|
||||
{
|
||||
const ecc_set_type* dp;
|
||||
int keySz;
|
||||
word32 ecdsel = 0; /* ecc parameters in hardware */
|
||||
int enc;
|
||||
status_t status;
|
||||
|
||||
ALIGN16 byte k[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
|
||||
ALIGN16 byte qx[MAX_ECC_BYTES] = {0};
|
||||
ALIGN16 byte qy[MAX_ECC_BYTES] = {0};
|
||||
ALIGN16 byte qxy[MAX_ECC_BYTES * 2] = {0};
|
||||
word32 qxSz, qySz;
|
||||
caam_handle_t hndl;
|
||||
|
||||
/* @TODO running on alternate job rings - performance enhancement */
|
||||
hndl.jobRing = kCAAM_JobRing0;
|
||||
|
||||
if (private_key->dp != NULL) {
|
||||
dp = private_key->dp;
|
||||
}
|
||||
else {
|
||||
dp = wc_ecc_get_curve_params(private_key->idx);
|
||||
}
|
||||
|
||||
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* check for known predetermined parameters */
|
||||
ecdsel = GetECDSEL(dp->id);
|
||||
if (ecdsel == 0) { /* predefined value not known, loading all parameters */
|
||||
WOLFSSL_MSG("Unsupported curve parameters");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
keySz = wc_ecc_size(private_key);
|
||||
if (*outlen < (word32)keySz) {
|
||||
WOLFSSL_MSG("out buffer is to small");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* public key */
|
||||
qxSz = qySz = MAX_ECC_BYTES;
|
||||
if (wc_ecc_export_public_raw(public_key, qx, &qxSz, qy, &qySz) != 0) {
|
||||
WOLFSSL_MSG("Issue exporting public key part");
|
||||
return -1;
|
||||
}
|
||||
XMEMCPY(qxy, qx, qxSz);
|
||||
XMEMCPY(qxy+qxSz, qy, qySz);
|
||||
|
||||
/* private key */
|
||||
if (keySz > MAX_ECC_BYTES) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
enc = 0;
|
||||
if (private_key->blackKey == CAAM_BLACK_KEY_ECB) {
|
||||
enc = CAAM_PKHA_ENC_PRI_AESECB;
|
||||
}
|
||||
|
||||
if (private_key->blackKey == CAAM_BLACK_KEY_CCM) {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(private_key), k,
|
||||
keySz + WC_CAAM_MAC_SZ) != MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(private_key), k, keySz)
|
||||
!= MP_OKAY) {
|
||||
return MP_TO_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (*outlen < (word32)keySz) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = CAAM_ECC_ECDH(CAAM, &hndl, k, keySz, qxy, keySz*2, out, keySz,
|
||||
ecdsel, enc);
|
||||
if (status == kStatus_Success) {
|
||||
*outlen = keySz;
|
||||
return MP_OKAY;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
/* creates a [ private black key ] [ x , y ]
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId,
|
||||
int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
ALIGN16 byte xy[MAX_ECC_BYTES * 2];
|
||||
ALIGN16 byte k[MAX_ECC_BYTES];
|
||||
word32 kSz = MAX_ECC_BYTES;
|
||||
word32 xySz = MAX_ECC_BYTES * 2;
|
||||
word32 ecdsel;
|
||||
word32 enc;
|
||||
status_t status;
|
||||
caam_handle_t hndl;
|
||||
|
||||
XMEMSET(xy, 0, MAX_ECC_BYTES * 2);
|
||||
XMEMSET(k, 0, MAX_ECC_BYTES);
|
||||
|
||||
/* @TODO running on alternate job rings - performance enhancement */
|
||||
hndl.jobRing = kCAAM_JobRing0;
|
||||
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
|
||||
/* if set to default curve then assume SECP256R1 */
|
||||
if (keySize == 32 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP256R1;
|
||||
if (keySize == 48 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP384R1;
|
||||
|
||||
if (curveId != ECC_SECP256R1 && curveId != ECC_SECP384R1) {
|
||||
/* currently only implemented P256/P384 support */
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
ecdsel = GetECDSEL(curveId);
|
||||
if (ecdsel == 0) {
|
||||
WOLFSSL_MSG("unknown key type or size");
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (key->blackKey == CAAM_BLACK_KEY_ECB) {
|
||||
enc = CAAM_PKHA_ENC_PRI_AESECB;
|
||||
}
|
||||
|
||||
if (key->blackKey == 0) {
|
||||
#ifdef WOLFSSL_CAAM_NO_BLACK_KEY
|
||||
enc = 0;
|
||||
#else
|
||||
key->blackKey = CAAM_BLACK_KEY_ECB;
|
||||
enc = CAAM_PKHA_ENC_PRI_AESECB;
|
||||
#endif
|
||||
}
|
||||
|
||||
status = CAAM_ECC_Keygen(CAAM, &hndl, k, &kSz, xy, &xySz, ecdsel,
|
||||
enc);
|
||||
if (status != kStatus_Success) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0 &&
|
||||
wc_ecc_import_unsigned(key, xy, xy + keySize, k, curveId) != 0) {
|
||||
WOLFSSL_MSG("issue importing key");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_KEY_GEN */
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
|
||||
/* Do a synchronous operations and block till done
|
||||
* returns 0 on success */
|
||||
int SynchronousSendRequest(int type, unsigned int args[4], CAAM_BUFFER *buf,
|
||||
int sz)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
caam_handle_t hndl;
|
||||
hndl.jobRing = kCAAM_JobRing0;
|
||||
|
||||
switch (type) {
|
||||
case CAAM_ENTROPY:
|
||||
if (CAAM_RNG_GetRandomData(CAAM, &hndl, kCAAM_RngStateHandle0,
|
||||
(uint8_t *)buf[0].TheAddress, buf[0].Length,
|
||||
kCAAM_RngDataAny, NULL) != kStatus_Success) {
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef NO_AES_CBC
|
||||
case CAAM_AESCBC:
|
||||
ret = DoAesCBC(args, buf, sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
case CAAM_AESCTR:
|
||||
ret = DoAesCTR(args, buf, sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CAAM_BLOB_EXPANSION
|
||||
case CAAM_BLOB_ENCAP:
|
||||
if (CAAM_Blob(CAAM, &hndl, (byte*)buf[1].TheAddress,
|
||||
buf[1].Length, (byte*)buf[2].TheAddress,
|
||||
buf[2].Length, (byte*)buf[0].TheAddress,
|
||||
buf[0].Length, CAAM_ENCAP_BLOB,
|
||||
(args[0] == 0)? CAAM_RED_BLOB : CAAM_BLACK_BLOB)
|
||||
!= kStatus_Success) {
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAAM_BLOB_DECAP:
|
||||
if (CAAM_Blob(CAAM, &hndl, (byte*)buf[1].TheAddress, buf[1].Length,
|
||||
(byte*)buf[2].TheAddress, buf[2].Length,
|
||||
(byte*)buf[0].TheAddress, buf[0].Length,
|
||||
CAAM_DECAP_BLOB,
|
||||
(args[0] == 0)? CAAM_RED_BLOB : CAAM_BLACK_BLOB)
|
||||
!= kStatus_Success) {
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown/unsupported type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_IMXRT1170_CAAM */
|
@ -0,0 +1,404 @@
|
||||
/* wolfcaam_hash.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>
|
||||
|
||||
#if defined(WOLFSSL_CAAM) && defined(WOLFSSL_CAAM_HASH) \
|
||||
&& !defined(WOLFSSL_IMXRT1170_CAAM)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
#include <INTEGRITY.h>
|
||||
#endif
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
#include <wolfssl/wolfcrypt/sha.h>
|
||||
#endif
|
||||
|
||||
#if !defined(NO_SHA256) || defined(WOLFSSL_SHA224)
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
|
||||
#include <wolfssl/wolfcrypt/sha512.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_MD5
|
||||
#include <wolfssl/wolfcrypt/md5.h>
|
||||
#endif
|
||||
|
||||
#ifndef WC_CAAM_CTXLEN
|
||||
#define WC_CAAM_CTXLEN 0
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
Common Code Between SHA Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef WOLFSSL_HASH_KEEP
|
||||
static int _ShaUpdate(byte* buffer, word32* buffLen, const byte* ctx,
|
||||
const byte* data, word32 len, word32 digestSz, word32 type)
|
||||
{
|
||||
CAAM_BUFFER buf[2];
|
||||
word32 arg[4];
|
||||
int ret;
|
||||
|
||||
if (buffer == NULL || ctx == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (len == 0) return 0; /* nothing to do */
|
||||
|
||||
/* check for filling out existing buffer */
|
||||
if (*buffLen > 0) {
|
||||
word32 add = min(len, WC_CAAM_HASH_BLOCK - *buffLen);
|
||||
XMEMCPY(&buffer[*buffLen], data, add);
|
||||
|
||||
*buffLen += add;
|
||||
data += add;
|
||||
len -= add;
|
||||
|
||||
if (*buffLen == WC_CAAM_HASH_BLOCK) {
|
||||
/* Set buffer for context */
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)sha->ctx;
|
||||
buf[idx].Length = digestSz + WC_CAAM_CTXLEN;
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
buf[idx].Transferred = 0;
|
||||
#endif
|
||||
idx++;
|
||||
|
||||
/* data to update with */
|
||||
buf[idx].BufferType = DataBuffer | LastBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)sha->buffer;
|
||||
buf[idx].Length = *buffLen;
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
buf[idx].Transferred = 0;
|
||||
#endif
|
||||
idx++;
|
||||
|
||||
arg[0] = CAAM_ALG_UPDATE;
|
||||
arg[1] = digestSz + WC_CAAM_CTXLEN;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, idx, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM SHA update");
|
||||
return ret;
|
||||
}
|
||||
*buffLen = 0; /* cleared out buffer */
|
||||
}
|
||||
}
|
||||
|
||||
/* check if multiple full blocks can be done */
|
||||
if (len >= WC_CAAM_HASH_BLOCK) {
|
||||
word32 sz = len / WC_CAAM_HASH_BLOCK;
|
||||
sz = sz * WC_CAAM_HASH_BLOCK;
|
||||
idx = 0;
|
||||
|
||||
/* Set buffer for context */
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)sha->ctx;
|
||||
buf[idx].Length = digestSz + WC_CAAM_CTXLEN;
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
buf[idx].Transferred = 0;
|
||||
#endif
|
||||
idx++;
|
||||
|
||||
/* data to update with */
|
||||
buf[idx].BufferType = DataBuffer | LastBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)data;
|
||||
buf[idx].Length = sz;
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
buf[idx].Transferred = 0;
|
||||
#endif
|
||||
idx++;
|
||||
|
||||
arg[0] = CAAM_ALG_UPDATE;
|
||||
arg[1] = digestSz + WC_CAAM_CTXLEN;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, idx, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM SHA update");
|
||||
return ret;
|
||||
}
|
||||
|
||||
len -= sz;
|
||||
data += sz;
|
||||
}
|
||||
|
||||
/* check for left overs */
|
||||
if (len > 0) {
|
||||
word32 add = min(len, WC_CAAM_HASH_BLOCK - *buffLen);
|
||||
XMEMCPY(&buffer[*buffLen], data, add);
|
||||
*buffLen += add;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !WOLFSSL_HASH_KEEP */
|
||||
|
||||
|
||||
static int _ShaFinal(byte* ctx, word32 ctxSz, byte* in, word32 inSz, byte* out,
|
||||
word32 type)
|
||||
{
|
||||
CAAM_BUFFER buf[2];
|
||||
word32 arg[4];
|
||||
int ret, idx = 0;
|
||||
|
||||
if (ctx == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Set buffer for context */
|
||||
buf[idx].BufferType = DataBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)ctx;
|
||||
buf[idx].Length = ctxSz;
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
buf[idx].Transferred = 0;
|
||||
#endif
|
||||
idx++;
|
||||
|
||||
/* add any potential left overs */
|
||||
buf[idx].BufferType = DataBuffer | LastBuffer;
|
||||
buf[idx].TheAddress = (CAAM_ADDRESS)in;
|
||||
buf[idx].Length = inSz;
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
buf[idx].Transferred = 0;
|
||||
#endif
|
||||
idx++;
|
||||
|
||||
arg[0] = CAAM_ALG_FINAL;
|
||||
arg[1] = ctxSz + WC_CAAM_CTXLEN;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, idx, arg, type)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM SHA Final");
|
||||
return ret;
|
||||
}
|
||||
XMEMCPY(out, ctx, ctxSz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 1
|
||||
****************************************************************************/
|
||||
#if !defined(NO_SHA)
|
||||
int wc_CAAM_ShaHash(wc_Sha* sha, const byte* in, word32 inSz, byte* digest)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* in the case of update's just store up all data */
|
||||
if (in != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
ret = _wc_Hash_Grow(&(sha->msg), &(sha->used), &(sha->len), in,
|
||||
inSz, sha->heap);
|
||||
#else
|
||||
ret = _ShaUpdate((byte*)sha->buffer, &sha->buffLen, (byte*)sha->digest,
|
||||
in, inSz, SHA_DIGEST_SIZE, CAAM_SHA);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (digest != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
int devId = sha->devId;
|
||||
void* heap = sha->heap;
|
||||
|
||||
ret = _ShaFinal((byte*)sha->digest, SHA_DIGEST_SIZE, sha->msg,
|
||||
sha->used, digest, CAAM_SHA);
|
||||
|
||||
wc_ShaFree(sha);
|
||||
wc_InitSha_ex(sha, heap, devId);
|
||||
#else
|
||||
ret = _ShaFinal((byte*)sha->digest, SHA_DIGEST_SIZE,
|
||||
(byte*)sha->buffer, sha->buffLen, digest, CAAM_SHA);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 224
|
||||
****************************************************************************/
|
||||
#ifdef WOLFSSL_SHA224
|
||||
int wc_CAAM_Sha224Hash(wc_Sha224* sha224, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* in the case of update's just store up all data */
|
||||
if (in != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
ret = wc_Sha224_Grow(sha224, in, inSz);
|
||||
#else
|
||||
ret = _ShaUpdate(sha224->buffer, &sha224->bufferLen,
|
||||
(byte*)sha224->digest, data, len, SHA224_DIGEST_SIZE, CAAM_SHA224);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (digest != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
int devId = sha224->devId;
|
||||
void* heap = sha224->heap;
|
||||
|
||||
ret = _ShaFinal((byte*)sha224->digest, SHA224_DIGEST_SIZE, sha224->msg,
|
||||
sha224->used, digest, CAAM_SHA224);
|
||||
wc_Sha224Free(sha224);
|
||||
wc_InitSha224_ex(sha224, heap, devId);
|
||||
#else
|
||||
ret = _ShaFinal((byte*)sha224->digest, SHA224_DIGEST_SIZE,
|
||||
(byte*)sha224->buffer, sha224->bufferLen, digest, CAAM_SHA224);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_SHA224 */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 256
|
||||
****************************************************************************/
|
||||
#if !defined(NO_SHA256)
|
||||
int wc_CAAM_Sha256Hash(wc_Sha256* sha256, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* in the case of update's just store up all data */
|
||||
if (in != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
ret = wc_Sha256_Grow(sha256, in, inSz);
|
||||
#else
|
||||
ret = _ShaUpdate((byte*)sha256->buffer, &sha256->buffLen,
|
||||
(byte*)sha256->digest, in, inSz, SHA256_DIGEST_SIZE, CAAM_SHA256);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (digest != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
int devId = sha256->devId;
|
||||
void* heap = sha256->heap;
|
||||
|
||||
ret = _ShaFinal((byte*)sha256->digest, SHA256_DIGEST_SIZE, sha256->msg,
|
||||
sha256->used, digest, CAAM_SHA256);
|
||||
|
||||
wc_Sha256Free(sha256);
|
||||
wc_InitSha256_ex(sha256, heap, devId);
|
||||
#else
|
||||
ret = _ShaFinal((byte*)sha256->digest, SHA256_DIGEST_SIZE,
|
||||
(byte*)sha256->buffer, sha256->buffLen, digest, CAAM_SHA256);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 384
|
||||
****************************************************************************/
|
||||
#ifdef WOLFSSL_SHA384
|
||||
int wc_CAAM_Sha384Hash(wc_Sha384* sha384, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* in the case of update's just store up all data */
|
||||
if (in != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
ret = wc_Sha384_Grow(sha384, in, inSz);
|
||||
#else
|
||||
ret = _ShaUpdate((byte*)sha384->buffer, &sha384->buffLen,
|
||||
(byte*)sha384->digest, in, inSz, SHA384_DIGEST_SIZE, CAAM_SHA384);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (digest != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
int devId = sha384->devId;
|
||||
void* heap = sha384->heap;
|
||||
|
||||
ret = _ShaFinal((byte*)sha384->digest, SHA384_DIGEST_SIZE, sha384->msg,
|
||||
sha384->used, digest, CAAM_SHA384);
|
||||
wc_Sha384Free(sha384);
|
||||
wc_InitSha384_ex(sha384, heap, devId);
|
||||
#else
|
||||
ret = _ShaFinal((byte*)sha384->digest, SHA384_DIGEST_SIZE,
|
||||
(byte*)sha384->buffer, sha384->buffLen, digest, CAAM_SHA384);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
SHA 512
|
||||
****************************************************************************/
|
||||
#ifdef WOLFSSL_SHA512
|
||||
int wc_CAAM_Sha512Hash(wc_Sha512* sha512, const byte* in, word32 inSz,
|
||||
byte* digest)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* in the case of update's just store up all data */
|
||||
if (in != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
ret = wc_Sha512_Grow(sha512, in, inSz);
|
||||
#else
|
||||
ret = _ShaUpdate((byte*)sha512->buffer, &sha512->buffLen,
|
||||
(byte*)sha512->digest, in, inSz, SHA512_DIGEST_SIZE, CAAM_SHA512);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (digest != NULL) {
|
||||
#ifdef WOLFSSL_HASH_KEEP
|
||||
int devId = sha512->devId;
|
||||
void* heap = sha512->heap;
|
||||
|
||||
ret = _ShaFinal((byte*)sha512->digest, SHA512_DIGEST_SIZE, sha512->msg,
|
||||
sha512->used, digest, CAAM_SHA512);
|
||||
wc_Sha512Free(sha512);
|
||||
wc_InitSha512_ex(sha512, heap, devId);
|
||||
#else
|
||||
ret = _ShaFinal((byte*)sha512->digest, SHA512_DIGEST_SIZE,
|
||||
(byte*)sha512->buffer, sha512->buffLen, digest, CAAM_SHA512);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
|
||||
#endif /* WOLFSSL_CAAM && WOLFSSL_CAAM_HASH */
|
||||
|
@ -0,0 +1,100 @@
|
||||
/* wolfcaam_hmac.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>
|
||||
|
||||
#if defined(WOLFSSL_CAAM) && !defined(NO_HMAC) && defined(WOLFSSL_CAAM_HMAC)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/coding.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_DEVCRYPTO_HMAC)
|
||||
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
|
||||
|
||||
/* HSM lib does not support HMAC with QXP board, use devcrypto instead */
|
||||
int wc_CAAM_Hmac(Hmac* hmac, int macType, const byte* msg, int msgSz,
|
||||
byte* digest)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (hmac->ctx.cfd == -1 && hmac->keyLen > 0) {
|
||||
ret = wc_DevCrypto_HmacSetKey(hmac, macType, hmac->keyRaw,
|
||||
hmac->keyLen);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Error with set key");
|
||||
if (ret == WC_NO_ERR_TRACE(HASH_TYPE_E)) {
|
||||
ret = CRYPTOCB_UNAVAILABLE; /* that hash type is not supported*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && msgSz > 0) {
|
||||
ret = wc_DevCrypto_HmacUpdate(hmac, msg, msgSz);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Issue with hmac update");
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && digest != NULL) {
|
||||
ret = wc_DevCrypto_HmacFinal(hmac, digest);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Issue with hmac final");
|
||||
}
|
||||
else {
|
||||
wc_DevCrypto_HmacFree(hmac);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int wc_CAAM_Hmac(Hmac* hmac, int macType, const byte* msg, int msgSz,
|
||||
byte* digest)
|
||||
{
|
||||
(void)hmac;
|
||||
(void)macType;
|
||||
(void)msg;
|
||||
(void)msgSz;
|
||||
(void)digest;
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
#endif /* WOLFSSL_DEVCRYPTO_HMAC */
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,838 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
* WOLFSSL_CAAM is used to enable CAAM support
|
||||
*
|
||||
* Different Hardware Ports
|
||||
* WOLFSSL_IMX6_CAAM build for QNX + IMX6
|
||||
* WOLFSSL_SECO_CAAM make use of NXP's SECO HSM library on i.MX8
|
||||
* WOLFSSL_IMXRT1170_CAAM make use of NXP's CAAM driver for RT1170 series boards
|
||||
*
|
||||
*/
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
|
||||
#ifdef DEBUG_WOLFSSL
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* determine which porting header to include */
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
#ifndef WC_CAAM_PASSWORD
|
||||
#define WC_CAAM_PASSWORD "!systempassword"
|
||||
#endif
|
||||
|
||||
#include <INTEGRITY.h>
|
||||
static IODevice caam = NULLIODevice;
|
||||
#define CAAM_SEND_REQUEST(type, sz, arg, buf) \
|
||||
SynchronousSendIORequest(caam, (type), (const Value*)(arg), (buf))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
/* Allow runtime setting for CAAM IODevice in case user wants to use password
|
||||
* at run time.
|
||||
*
|
||||
* returns 0 on success
|
||||
*
|
||||
* NOTE this is how IODevice is defined in INTEGRITY "typedef struct
|
||||
* IODeviceStruct *IODevice;"
|
||||
*/
|
||||
int wc_caamSetResource(IODevice ioDev)
|
||||
{
|
||||
WOLFSSL_MSG("Setting CAAM driver");
|
||||
caam = ioDev;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* used to route crypto operations through crypto callback */
|
||||
static int wc_CAAM_router(int devId, wc_CryptoInfo* info, void* ctx)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
|
||||
(void)ctx;
|
||||
(void)devId;
|
||||
switch (info->algo_type) {
|
||||
case WC_ALGO_TYPE_PK:
|
||||
switch (info->pk.type) {
|
||||
#if defined(HAVE_ECC) && defined(WOLFSSL_CAAM_ECC)
|
||||
case WC_PK_TYPE_ECDSA_SIGN:
|
||||
ret = wc_CAAM_EccSign(info->pk.eccsign.in,
|
||||
info->pk.eccsign.inlen, info->pk.eccsign.out,
|
||||
info->pk.eccsign.outlen, info->pk.eccsign.rng,
|
||||
info->pk.eccsign.key, devId);
|
||||
break;
|
||||
|
||||
case WC_PK_TYPE_ECDSA_VERIFY:
|
||||
ret = wc_CAAM_EccVerify(info->pk.eccverify.sig,
|
||||
info->pk.eccverify.siglen, info->pk.eccverify.hash,
|
||||
info->pk.eccverify.hashlen, info->pk.eccverify.res,
|
||||
info->pk.eccverify.key, devId);
|
||||
break;
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
case WC_PK_TYPE_EC_KEYGEN:
|
||||
ret = wc_CAAM_MakeEccKey(info->pk.eckg.rng,
|
||||
info->pk.eckg.size, info->pk.eckg.key,
|
||||
info->pk.eckg.curveId, devId);
|
||||
break;
|
||||
#endif /* WOLFSSL_KEY_GEN */
|
||||
|
||||
case WC_PK_TYPE_ECDH:
|
||||
ret = wc_CAAM_Ecdh(info->pk.ecdh.private_key,
|
||||
info->pk.ecdh.public_key,
|
||||
info->pk.ecdh.out,
|
||||
info->pk.ecdh.outlen, devId);
|
||||
break;
|
||||
|
||||
case WC_PK_TYPE_EC_CHECK_PRIV_KEY:
|
||||
ret = wc_CAAM_EccCheckPrivKey(info->pk.ecc_check.key,
|
||||
info->pk.ecc_check.pubKey,
|
||||
info->pk.ecc_check.pubKeySz);
|
||||
break;
|
||||
#endif /* HAVE_ECC && WOLFSSL_CAAM_ECC */
|
||||
#if !defined(NO_RSA) && defined(WOLFSSL_DEVCRYPTO_RSA)
|
||||
case WC_PK_TYPE_RSA:
|
||||
ret = wc_CAAM_Rsa(info->pk.rsa.in,
|
||||
info->pk.rsa.inLen,
|
||||
info->pk.rsa.out,
|
||||
info->pk.rsa.outLen,
|
||||
info->pk.rsa.type,
|
||||
info->pk.rsa.key,
|
||||
info->pk.rsa.rng);
|
||||
break;
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
case WC_PK_TYPE_RSA_KEYGEN:
|
||||
ret = wc_CAAM_MakeRsaKey(info->pk.rsakg.key,
|
||||
info->pk.rsakg.size,
|
||||
info->pk.rsakg.e,
|
||||
info->pk.rsakg.rng);
|
||||
break;
|
||||
#endif
|
||||
#endif /* !NO_RSA */
|
||||
#if defined(HAVE_CURVE25519) && defined(WOLFSSL_CAAM_CURVE25519)
|
||||
case WC_PK_TYPE_CURVE25519_KEYGEN:
|
||||
ret = wc_CAAM_MakeCurve25519Key(info->pk.curve25519kg.key,
|
||||
info->pk.curve25519kg.size,
|
||||
info->pk.curve25519kg.rng);
|
||||
break;
|
||||
|
||||
case WC_PK_TYPE_CURVE25519:
|
||||
ret = wc_CAAM_Curve25519(info->pk.curve25519.out,
|
||||
info->pk.curve25519.outlen,
|
||||
info->pk.curve25519.private_key,
|
||||
info->pk.curve25519.public_key,
|
||||
info->pk.curve25519.endian);
|
||||
break;
|
||||
#endif /* HAVE_CURVE25519 && WOLFSSL_CAAM_CURVE25519 */
|
||||
default:
|
||||
WOLFSSL_MSG("unsupported public key operation");
|
||||
}
|
||||
break;
|
||||
|
||||
case WC_ALGO_TYPE_CMAC:
|
||||
#if defined(WOLFSSL_CMAC) && defined(WOLFSSL_CAAM_CMAC)
|
||||
#ifdef WOLFSSL_SECO_CAAM
|
||||
if (devId != WOLFSSL_SECO_DEVID)
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && \
|
||||
defined(WOLFSSL_AES_DIRECT)
|
||||
ret = wc_CAAM_Cmac(info->cmac.cmac,
|
||||
info->cmac.key,
|
||||
info->cmac.keySz,
|
||||
info->cmac.in,
|
||||
info->cmac.inSz,
|
||||
info->cmac.out,
|
||||
info->cmac.outSz,
|
||||
info->cmac.type,
|
||||
info->cmac.ctx);
|
||||
#else
|
||||
WOLFSSL_MSG("CMAC not compiled in");
|
||||
ret = NOT_COMPILED_IN;
|
||||
#endif
|
||||
#endif /* WOLFSSL_CMAC && WOLFSSL_CAAM_CMAC */
|
||||
break;
|
||||
|
||||
case WC_ALGO_TYPE_HASH:
|
||||
#ifdef WOLFSSL_CAAM_HASH
|
||||
switch(info->hash.type) {
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case WC_HASH_TYPE_SHA224:
|
||||
ret = wc_CAAM_Sha224Hash(info->hash.sha224,
|
||||
info->hash.in,
|
||||
info->hash.inSz,
|
||||
info->hash.digest);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case WC_HASH_TYPE_SHA256:
|
||||
ret = wc_CAAM_Sha256Hash(info->hash.sha256,
|
||||
info->hash.in,
|
||||
info->hash.inSz,
|
||||
info->hash.digest);
|
||||
break;
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_HASH_TYPE_SHA384:
|
||||
ret = wc_CAAM_Sha384Hash(info->hash.sha384,
|
||||
info->hash.in,
|
||||
info->hash.inSz,
|
||||
info->hash.digest);
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_HASH_TYPE_SHA512:
|
||||
ret = wc_CAAM_Sha512Hash(info->hash.sha512,
|
||||
info->hash.in,
|
||||
info->hash.inSz,
|
||||
info->hash.digest);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown or unsupported hash type");
|
||||
ret = CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
#endif /* WOLFSSL_CAAM_HASH */
|
||||
break;
|
||||
|
||||
case WC_ALGO_TYPE_HMAC:
|
||||
#if defined(WOLFSSL_CAAM_HMAC)
|
||||
ret = wc_CAAM_Hmac(info->hmac.hmac,
|
||||
info->hmac.macType,
|
||||
info->hmac.in, info->hmac.inSz,
|
||||
info->hmac.digest);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WC_ALGO_TYPE_CIPHER:
|
||||
#if defined(WOLFSSL_CAAM_CIPHER)
|
||||
#ifdef WOLFSSL_SECO_CAAM
|
||||
if (devId != WOLFSSL_SECO_DEVID)
|
||||
break; /* only call to SECO if using WOLFSSL_SECO_DEVID */
|
||||
#endif
|
||||
switch (info->cipher.type) {
|
||||
#if defined(HAVE_AESCCM) && defined(WOLFSSL_CAAM_AESCCM)
|
||||
case WC_CIPHER_AES_CCM:
|
||||
if (info->cipher.enc == 1) {
|
||||
ret = wc_CAAM_AesCcmEncrypt(
|
||||
info->cipher.aesccm_enc.aes,
|
||||
info->cipher.aesccm_enc.in,
|
||||
info->cipher.aesccm_enc.out,
|
||||
info->cipher.aesccm_enc.sz,
|
||||
info->cipher.aesccm_enc.nonce,
|
||||
info->cipher.aesccm_enc.nonceSz,
|
||||
info->cipher.aesccm_enc.authTag,
|
||||
info->cipher.aesccm_enc.authTagSz,
|
||||
info->cipher.aesccm_enc.authIn,
|
||||
info->cipher.aesccm_enc.authInSz);
|
||||
}
|
||||
else {
|
||||
ret = wc_CAAM_AesCcmDecrypt(
|
||||
info->cipher.aesccm_dec.aes,
|
||||
info->cipher.aesccm_dec.in,
|
||||
info->cipher.aesccm_dec.out,
|
||||
info->cipher.aesccm_dec.sz,
|
||||
info->cipher.aesccm_dec.nonce,
|
||||
info->cipher.aesccm_dec.nonceSz,
|
||||
info->cipher.aesccm_dec.authTag,
|
||||
info->cipher.aesccm_dec.authTagSz,
|
||||
info->cipher.aesccm_dec.authIn,
|
||||
info->cipher.aesccm_dec.authInSz);
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_AESCCM */
|
||||
#if defined(HAVE_AESGCM) && defined(WOLFSSL_CAAM_AESGCM)
|
||||
case WC_CIPHER_AES_GCM:
|
||||
if (info->cipher.enc == 1) {
|
||||
ret = wc_CAAM_AesGcmEncrypt(
|
||||
info->cipher.aesgcm_enc.aes,
|
||||
info->cipher.aesgcm_enc.in,
|
||||
info->cipher.aesgcm_enc.out,
|
||||
info->cipher.aesgcm_enc.sz,
|
||||
info->cipher.aesgcm_enc.iv,
|
||||
info->cipher.aesgcm_enc.ivSz,
|
||||
info->cipher.aesgcm_enc.authTag,
|
||||
info->cipher.aesgcm_enc.authTagSz,
|
||||
info->cipher.aesgcm_enc.authIn,
|
||||
info->cipher.aesgcm_enc.authInSz);
|
||||
}
|
||||
else {
|
||||
ret = wc_CAAM_AesGcmDecrypt(
|
||||
info->cipher.aesgcm_dec.aes,
|
||||
info->cipher.aesgcm_dec.in,
|
||||
info->cipher.aesgcm_dec.out,
|
||||
info->cipher.aesgcm_dec.sz,
|
||||
info->cipher.aesgcm_dec.iv,
|
||||
info->cipher.aesgcm_dec.ivSz,
|
||||
info->cipher.aesgcm_dec.authTag,
|
||||
info->cipher.aesgcm_dec.authTagSz,
|
||||
info->cipher.aesgcm_dec.authIn,
|
||||
info->cipher.aesgcm_dec.authInSz);
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_AESGCM && WOLFSSL_CAAM_AESGCM */
|
||||
|
||||
case WC_CIPHER_AES_CBC:
|
||||
if (info->cipher.enc == 1) {
|
||||
ret = wc_CAAM_AesCbcEncrypt(info->cipher.aescbc.aes,
|
||||
info->cipher.aescbc.out,
|
||||
info->cipher.aescbc.in,
|
||||
info->cipher.aescbc.sz);
|
||||
}
|
||||
else {
|
||||
ret = wc_CAAM_AesCbcDecrypt(info->cipher.aescbc.aes,
|
||||
info->cipher.aescbc.out,
|
||||
info->cipher.aescbc.in,
|
||||
info->cipher.aescbc.sz);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
case WC_CIPHER_AES_CTR:
|
||||
ret = wc_CAAM_AesCtrEncrypt(info->cipher.aesctr.aes,
|
||||
info->cipher.aesctr.out,
|
||||
info->cipher.aesctr.in,
|
||||
info->cipher.aesctr.sz);
|
||||
break;
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
|
||||
#if defined(HAVE_AES_ECB)
|
||||
case WC_CIPHER_AES_ECB:
|
||||
if (info->cipher.enc == 1) {
|
||||
ret = wc_CAAM_AesEcbEncrypt(info->cipher.aesecb.aes,
|
||||
info->cipher.aesecb.out,
|
||||
info->cipher.aesecb.in,
|
||||
info->cipher.aesecb.sz);
|
||||
}
|
||||
else {
|
||||
ret = wc_CAAM_AesEcbDecrypt(info->cipher.aesecb.aes,
|
||||
info->cipher.aesecb.out,
|
||||
info->cipher.aesecb.in,
|
||||
info->cipher.aesecb.sz);
|
||||
}
|
||||
#endif /* HAVE_AES_ECB */
|
||||
}
|
||||
#endif /* WOLFSSL_CAAM_CIPHER */
|
||||
break;
|
||||
|
||||
case WC_ALGO_TYPE_RNG:
|
||||
case WC_ALGO_TYPE_SEED:
|
||||
case WC_ALGO_TYPE_NONE:
|
||||
default:
|
||||
/* Not implemented yet with CAAM */
|
||||
ret = CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Check hardware support
|
||||
*
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_caamInit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_MSG("Starting interface with CAAM driver");
|
||||
if (CAAM_INIT_INTERFACE() != 0) {
|
||||
WOLFSSL_MSG("Error initializing CAAM");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* check that for implemented modules
|
||||
* bits 0-3 AES, 4-7 DES, 12-15 Hashing , 16-19 RNG, 28-31 public key module */
|
||||
reg = WC_CAAM_READ(CAMM_SUPPORT_LS);
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
if (((reg & 0x000F0000) >> 16) > 0) {
|
||||
WOLFSSL_MSG("Found CAAM RNG hardware module");
|
||||
if ((WC_CAAM_READ(CAAM_RTMCTL) & 0x40000001) != 0x40000001) {
|
||||
WOLFSSL_MSG("Error CAAM RNG has not been set up");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
if ((reg & 0x0000F000) > 0) {
|
||||
WOLFSSL_MSG("Found CAAM MDHA module");
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Hashing not supported by CAAM");
|
||||
return WC_HW_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_AES
|
||||
if ((reg & 0x0000000F) > 0) {
|
||||
WOLFSSL_MSG("Found CAAM AES module");
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("AES not supported by CAAM");
|
||||
return WC_HW_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
if ((reg & 0xF0000000) > 0) {
|
||||
WOLFSSL_MSG("Found CAAM Public Key module");
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Public Key not supported by CAAM");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SECO_CAAM
|
||||
ret = wc_CryptoDev_RegisterDevice(WOLFSSL_SECO_DEVID, wc_CAAM_router,
|
||||
NULL);
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
ret = wc_CryptoDev_RegisterDevice(WOLFSSL_CAAM_DEVID, wc_CAAM_router,
|
||||
NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* free up all resources used for CAAM */
|
||||
int wc_caamFree(void)
|
||||
{
|
||||
CAAM_FREE_INTERFACE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
word32 wc_caamReadRegister(word32 reg)
|
||||
{
|
||||
word32 out = 0;
|
||||
|
||||
if (caam == NULLIODevice) {
|
||||
WOLFSSL_MSG("Error CAAM IODevice not found! Bad password?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ReadIODeviceRegister(caam, reg, &out) != Success) {
|
||||
WOLFSSL_MSG("Error reading register");
|
||||
}
|
||||
|
||||
return (word32)out;
|
||||
}
|
||||
|
||||
|
||||
/* returns 0 on success */
|
||||
int wc_caamWriteRegister(word32 reg, word32 value)
|
||||
{
|
||||
if (caam == NULLIODevice) {
|
||||
WOLFSSL_MSG("Error CAAM IODevice not found! Bad password?");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WriteIODeviceRegister(caam, reg, value) != Success) {
|
||||
WOLFSSL_MSG("Error writing to register");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* return 0 on success and WC_HW_E on failure. Can also return WC_HW_WAIT_E
|
||||
* in the case that the driver is waiting for a resource or RAN_BLOCK_E if
|
||||
* waiting for entropy. */
|
||||
int wc_caamAddAndWait(CAAM_BUFFER* buf, int sz, word32 arg[4], word32 type)
|
||||
{
|
||||
int ret;
|
||||
#ifdef DEBUG_WOLFSSL
|
||||
static int wait = 0;
|
||||
#endif
|
||||
|
||||
#if defined(__INTEGRITY) || defined(INTEGRITY)
|
||||
if (caam == NULLIODevice) {
|
||||
WOLFSSL_MSG("Error CAAM IODevice not found! Bad password?");
|
||||
return WC_HW_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = CAAM_SEND_REQUEST(type, sz, arg, buf)) != Success) {
|
||||
/* if waiting for resource or RNG return waiting */
|
||||
if (ret == CAAM_WAITING) {
|
||||
#ifdef DEBUG_WOLFSSL
|
||||
if (wait == 0) {
|
||||
wait = 1;
|
||||
WOLFSSL_MSG("Waiting on entropy from driver");
|
||||
}
|
||||
fprintf(stderr, ".");
|
||||
#endif
|
||||
return RAN_BLOCK_E;
|
||||
}
|
||||
|
||||
if (ret == ResourceNotAvailable) {
|
||||
WOLFSSL_MSG("Waiting on CAAM driver");
|
||||
return WC_HW_WAIT_E;
|
||||
}
|
||||
|
||||
return WC_HW_E;
|
||||
}
|
||||
#ifdef DEBUG_WOLFSSL
|
||||
if (wait) {
|
||||
wait = 0;
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSL_CAAM_BLOB
|
||||
/* Create a red or black blob
|
||||
*
|
||||
* mod : key modifier, expected 8 bytes for RED key types and 16 for BLACK
|
||||
* if 'mod' is null than 0's are used
|
||||
*
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_caamCreateBlob_ex(byte* data, word32 dataSz, byte* out, word32* outSz,
|
||||
int type, byte* mod, word32 modSz)
|
||||
{
|
||||
CAAM_BUFFER in[3];
|
||||
word32 arg[4];
|
||||
int ret;
|
||||
byte local[WC_CAAM_BLACK_KEYMOD_SZ] = {0};
|
||||
byte* keyMod;
|
||||
int keyModSz;
|
||||
|
||||
keyMod = mod;
|
||||
XMEMSET(local, 0, sizeof(local));
|
||||
if (data == NULL || out == NULL || outSz == NULL ||
|
||||
*outSz < dataSz + WC_CAAM_BLOB_SZ) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (type == WC_CAAM_BLOB_RED) {
|
||||
arg[0] = 0;
|
||||
if (mod != NULL) {
|
||||
if (modSz != WC_CAAM_RED_KEYMOD_SZ) {
|
||||
WOLFSSL_MSG("bad key mod red size");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
keyModSz = WC_CAAM_RED_KEYMOD_SZ;
|
||||
}
|
||||
else if (type == WC_CAAM_BLOB_BLACK) {
|
||||
arg[0] = 1;
|
||||
if (mod != NULL) {
|
||||
if (modSz != WC_CAAM_BLACK_KEYMOD_SZ) {
|
||||
WOLFSSL_MSG("bad key mod black size");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
keyModSz = WC_CAAM_BLACK_KEYMOD_SZ;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("unknown blob type!");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (mod == NULL) {
|
||||
WOLFSSL_MSG("using local all 0's key modifier");
|
||||
keyMod = local;
|
||||
}
|
||||
|
||||
in[0].BufferType = DataBuffer;
|
||||
in[0].TheAddress = (CAAM_ADDRESS)keyMod;
|
||||
in[0].Length = keyModSz;
|
||||
|
||||
in[1].BufferType = DataBuffer;
|
||||
in[1].TheAddress = (CAAM_ADDRESS)data;
|
||||
in[1].Length = dataSz;
|
||||
|
||||
in[2].BufferType = DataBuffer | LastBuffer;
|
||||
in[2].TheAddress = (CAAM_ADDRESS)out;
|
||||
in[2].Length = dataSz + WC_CAAM_BLOB_SZ;
|
||||
|
||||
arg[2] = dataSz;
|
||||
arg[3] = keyModSz;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(in, 3, arg, CAAM_BLOB_ENCAP)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM blob create");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*outSz = dataSz + WC_CAAM_BLOB_SZ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* create a red key blob
|
||||
* returns 0 on success */
|
||||
int wc_caamCreateBlob(byte* data, word32 dataSz, byte* out, word32* outSz)
|
||||
{
|
||||
return wc_caamCreateBlob_ex(data, dataSz, out, outSz, WC_CAAM_BLOB_RED,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/* uncover black or red keys
|
||||
* returns 0 on success */
|
||||
int wc_caamOpenBlob_ex(byte* data, word32 dataSz, byte* out, word32* outSz,
|
||||
int type, byte* mod, word32 modSz)
|
||||
{
|
||||
CAAM_BUFFER in[3];
|
||||
word32 arg[4];
|
||||
int ret;
|
||||
byte local[WC_CAAM_BLACK_KEYMOD_SZ];
|
||||
byte* keyMod;
|
||||
int keyModSz;
|
||||
|
||||
keyMod = mod;
|
||||
XMEMSET(local, 0, sizeof(local));
|
||||
|
||||
if (data == NULL || out == NULL || outSz == NULL ||
|
||||
*outSz < dataSz - WC_CAAM_BLOB_SZ) {
|
||||
WOLFSSL_MSG("NULL argument or outSz is too small");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (type == WC_CAAM_BLOB_RED) {
|
||||
arg[0] = 0;
|
||||
if (mod != NULL) {
|
||||
if (modSz != WC_CAAM_RED_KEYMOD_SZ) {
|
||||
WOLFSSL_MSG("bad key mod red size");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
keyModSz = WC_CAAM_RED_KEYMOD_SZ;
|
||||
}
|
||||
else if (type == WC_CAAM_BLOB_BLACK) {
|
||||
arg[0] = 1;
|
||||
if (mod != NULL) {
|
||||
if (modSz != WC_CAAM_BLACK_KEYMOD_SZ) {
|
||||
WOLFSSL_MSG("bad key mod black size");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
keyModSz = WC_CAAM_BLACK_KEYMOD_SZ;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("unknown blob type!");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (mod == NULL) {
|
||||
WOLFSSL_MSG("using local all 0's key modifier");
|
||||
keyMod = local;
|
||||
}
|
||||
|
||||
in[0].BufferType = DataBuffer;
|
||||
in[0].TheAddress = (CAAM_ADDRESS)keyMod;
|
||||
in[0].Length = keyModSz;
|
||||
|
||||
in[1].BufferType = DataBuffer;
|
||||
in[1].TheAddress = (CAAM_ADDRESS)data;
|
||||
in[1].Length = dataSz;
|
||||
|
||||
in[2].BufferType = DataBuffer | LastBuffer;
|
||||
in[2].TheAddress = (CAAM_ADDRESS)out;
|
||||
in[2].Length = dataSz - WC_CAAM_BLOB_SZ;
|
||||
|
||||
arg[2] = dataSz;
|
||||
arg[3] = keyModSz;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(in, 3, arg, CAAM_BLOB_DECAP)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM blob open");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*outSz = dataSz - WC_CAAM_BLOB_SZ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* open a red blob
|
||||
* returns 0 on success */
|
||||
int wc_caamOpenBlob(byte* data, word32 dataSz, byte* out, word32* outSz)
|
||||
{
|
||||
return wc_caamOpenBlob_ex(data, dataSz, out, outSz, WC_CAAM_BLOB_RED,
|
||||
NULL, 0);
|
||||
}
|
||||
#endif /* WOLFSSL_CAAM_BLOB */
|
||||
|
||||
/* outSz gets set to key size plus 16 for mac and padding
|
||||
* return 0 on success
|
||||
*/
|
||||
int wc_caamCoverKey(byte* in, word32 inSz, byte* out, word32* outSz, int flag)
|
||||
{
|
||||
CAAM_BUFFER buf[2];
|
||||
word32 arg[4];
|
||||
int ret;
|
||||
|
||||
if (*outSz < inSz + WC_CAAM_MAC_SZ) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (CAAM_ADDRESS)in;
|
||||
buf[0].Length = inSz;
|
||||
|
||||
buf[1].BufferType = DataBuffer;
|
||||
buf[1].TheAddress = (CAAM_ADDRESS)out;
|
||||
buf[1].Length = inSz;
|
||||
|
||||
(void)flag; /* for now defaulting to use highest security AES-CCM here */
|
||||
arg[0] = CAAM_FIFO_CCM_FLAG;
|
||||
arg[1] = inSz;
|
||||
if ((ret = wc_caamAddAndWait(buf, 2, arg, CAAM_FIFO_S)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM blob create");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*outSz = inSz + WC_CAAM_MAC_SZ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* return 0 or greater on success for the partition number available
|
||||
* returns a negative value on failure
|
||||
*/
|
||||
int caamFindUnusedPartition()
|
||||
{
|
||||
CAAM_BUFFER buf[1];
|
||||
word32 arg[4];
|
||||
int ret = 0;
|
||||
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (CAAM_ADDRESS)&ret;
|
||||
buf[0].Length = sizeof(int);
|
||||
|
||||
if ((wc_caamAddAndWait(buf, 1, arg, CAAM_FIND_PART)) != 0) {
|
||||
WOLFSSL_MSG("Error finding a partition to use");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* return the address of the given partition number "part" */
|
||||
CAAM_ADDRESS caamGetPartition(int part, int sz)
|
||||
{
|
||||
CAAM_BUFFER buf[1];
|
||||
word32 arg[4];
|
||||
CAAM_ADDRESS ret = 0;
|
||||
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (CAAM_ADDRESS)(&ret);
|
||||
buf[0].Length = sizeof(int);
|
||||
|
||||
arg[0] = part;
|
||||
arg[1] = sz;
|
||||
|
||||
if ((wc_caamAddAndWait(buf, 1, arg, CAAM_GET_PART)) != 0) {
|
||||
WOLFSSL_MSG("Error getting a partition");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Internal function to free a secure partition
|
||||
* return 0 on success */
|
||||
int caamFreePart(int partNum)
|
||||
{
|
||||
word32 arg[4];
|
||||
|
||||
arg[0] = partNum;
|
||||
|
||||
if ((wc_caamAddAndWait(NULL, 0, arg, CAAM_FREE_PART)) != 0) {
|
||||
WOLFSSL_MSG("Error freeing a partition");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Internal function to help write to a secure partition
|
||||
* return 0 on success */
|
||||
int caamWriteToPartition(CAAM_ADDRESS addr, const unsigned char* in, int inSz)
|
||||
{
|
||||
CAAM_BUFFER buf[1];
|
||||
word32 arg[4];
|
||||
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (CAAM_ADDRESS)in;
|
||||
buf[0].Length = inSz;
|
||||
|
||||
arg[0] = addr;
|
||||
arg[1] = inSz;
|
||||
|
||||
if ((wc_caamAddAndWait(buf, 1, arg, CAAM_WRITE_PART)) != 0) {
|
||||
WOLFSSL_MSG("Error writing to a partition");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Internal function to help read from a secure partition
|
||||
* return 0 on success */
|
||||
int caamReadPartition(CAAM_ADDRESS addr, unsigned char* out, int outSz)
|
||||
{
|
||||
CAAM_BUFFER buf[1];
|
||||
word32 arg[4];
|
||||
|
||||
buf[0].BufferType = DataBuffer;
|
||||
buf[0].TheAddress = (CAAM_ADDRESS)out;
|
||||
buf[0].Length = outSz;
|
||||
|
||||
arg[0] = addr;
|
||||
arg[1] = outSz;
|
||||
|
||||
if ((wc_caamAddAndWait(buf, 1, arg, CAAM_READ_PART)) != 0) {
|
||||
WOLFSSL_MSG("Error reading a partition");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_CAAM */
|
@ -0,0 +1,469 @@
|
||||
/* wolfcaam_qnx.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>
|
||||
|
||||
#if defined(WOLFSSL_QNX_CAAM) && (defined(__QNX__) || defined(__QNXNTO__))
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <devctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* for devctl use */
|
||||
int caamFd = -1;
|
||||
static wolfSSL_Mutex caamMutex;
|
||||
|
||||
/* return 0 on success */
|
||||
int wc_CAAMInitInterface()
|
||||
{
|
||||
if (wc_InitMutex(&caamMutex) != 0) {
|
||||
WOLFSSL_MSG("Could not init mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
caamFd = open("/dev/wolfCrypt", O_RDWR);
|
||||
if (caamFd < 0) {
|
||||
WOLFSSL_MSG("Could not open /dev/wolfCrypt");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void wc_CAAMFreeInterface()
|
||||
{
|
||||
wc_FreeMutex(&caamMutex);
|
||||
if (caamFd >= 0)
|
||||
close(caamFd);
|
||||
}
|
||||
|
||||
#define WC_TRNG_CMD __DIOTF(_DCMD_ALL, CAAM_ENTROPY, iov_t)
|
||||
#define WC_CAAM_GET_PART __DIOTF(_DCMD_ALL, CAAM_GET_PART, iov_t)
|
||||
#define WC_CAAM_FREE_PART __DIOT(_DCMD_ALL, CAAM_FREE_PART, iov_t)
|
||||
#define WC_CAAM_FIND_PART __DIOTF(_DCMD_ALL, CAAM_FIND_PART, iov_t)
|
||||
#define WC_CAAM_READ_PART __DIOTF(_DCMD_ALL, CAAM_READ_PART, iov_t)
|
||||
#define WC_CAAM_WRITE_PART __DIOT(_DCMD_ALL, CAAM_WRITE_PART, iov_t)
|
||||
|
||||
#define WC_CAAM_ECDSA_KEYPAIR __DIOTF(_DCMD_ALL, CAAM_ECDSA_KEYPAIR, iov_t)
|
||||
#define WC_CAAM_ECDSA_VERIFY __DIOT(_DCMD_ALL, CAAM_ECDSA_VERIFY, iov_t)
|
||||
#define WC_CAAM_ECDSA_SIGN __DIOTF(_DCMD_ALL, CAAM_ECDSA_SIGN, iov_t)
|
||||
#define WC_CAAM_ECDSA_ECDH __DIOTF(_DCMD_ALL, CAAM_ECDSA_ECDH, iov_t)
|
||||
|
||||
#define WC_CAAM_BLOB_ENCAP __DIOTF(_DCMD_ALL, CAAM_BLOB_ENCAP, iov_t)
|
||||
#define WC_CAAM_BLOB_DECAP __DIOTF(_DCMD_ALL, CAAM_BLOB_DECAP, iov_t)
|
||||
|
||||
#define WC_CAAM_CMAC __DIOTF(_DCMD_ALL, CAAM_CMAC, iov_t)
|
||||
#define WC_CAAM_AESECB __DIOTF(_DCMD_ALL, CAAM_AESECB, iov_t)
|
||||
#define WC_CAAM_AESCTR __DIOTF(_DCMD_ALL, CAAM_AESCTR, iov_t)
|
||||
#define WC_CAAM_AESCBC __DIOTF(_DCMD_ALL, CAAM_AESCBC, iov_t)
|
||||
#define WC_CAAM_AESCCM __DIOTF(_DCMD_ALL, CAAM_AESCCM, iov_t)
|
||||
#define WC_CAAM_AESGCM __DIOTF(_DCMD_ALL, CAAM_AESGCM, iov_t)
|
||||
|
||||
#define WC_CAAM_FIFO_S __DIOTF(_DCMD_ALL, CAAM_FIFO_S, iov_t)
|
||||
|
||||
#define MAX_IN_IOVS 6
|
||||
#define MAX_OUT_IOVS 3
|
||||
|
||||
/* Do a synchronous operations and block till done
|
||||
* returns 0 on success */
|
||||
int SynchronousSendRequest(int type, unsigned int args[4], CAAM_BUFFER *buf,
|
||||
int sz)
|
||||
{
|
||||
int ret, inIdx = 0, outIdx = 0;
|
||||
int cmd = 0;
|
||||
iov_t in[MAX_IN_IOVS], out[MAX_OUT_IOVS];
|
||||
CAAM_ADDRESS privkey;
|
||||
|
||||
if (args != NULL) {
|
||||
SETIOV(&in[inIdx], args, sizeof(unsigned int) * 4);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
else {
|
||||
unsigned int localArgs[4] = {0};
|
||||
SETIOV(&in[inIdx], localArgs, sizeof(unsigned int) * 4);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case CAAM_ENTROPY:
|
||||
SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
|
||||
outIdx = outIdx + 1;
|
||||
cmd = WC_TRNG_CMD;
|
||||
break;
|
||||
|
||||
case CAAM_GET_PART:
|
||||
SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
|
||||
outIdx = outIdx + 1;
|
||||
cmd = WC_CAAM_GET_PART;
|
||||
break;
|
||||
|
||||
case CAAM_FREE_PART:
|
||||
cmd = WC_CAAM_FREE_PART;
|
||||
break;
|
||||
|
||||
case CAAM_FIND_PART:
|
||||
SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
|
||||
outIdx = outIdx + 1;
|
||||
cmd = WC_CAAM_FIND_PART;
|
||||
break;
|
||||
|
||||
case CAAM_READ_PART:
|
||||
SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
|
||||
outIdx = outIdx + 1;
|
||||
cmd = WC_CAAM_READ_PART;
|
||||
break;
|
||||
|
||||
case CAAM_WRITE_PART:
|
||||
SETIOV(&in[inIdx], (buf->TheAddress), (buf->Length));
|
||||
inIdx = inIdx + 1;
|
||||
cmd = WC_CAAM_WRITE_PART;
|
||||
break;
|
||||
|
||||
case CAAM_ECDSA_KEYPAIR:
|
||||
/* set output to store directly to CAAM_BUFFER's */
|
||||
SETIOV(&out[outIdx], buf[0].TheAddress, buf[0].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
SETIOV(&out[outIdx], buf[1].TheAddress, buf[1].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
/* get args for updated partition number used */
|
||||
SETIOV(&out[outIdx], args, sizeof(unsigned int) * 4);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_ECDSA_KEYPAIR;
|
||||
break;
|
||||
|
||||
case CAAM_ECDSA_VERIFY:
|
||||
/* public key */
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* msg */
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* r */
|
||||
SETIOV(&in[inIdx], buf[2].TheAddress, buf[2].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* s */
|
||||
SETIOV(&in[inIdx], buf[3].TheAddress, buf[3].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_ECDSA_VERIFY;
|
||||
break;
|
||||
|
||||
case CAAM_ECDSA_SIGN:
|
||||
/* private key */
|
||||
if (args[0] == 1) {
|
||||
privkey = buf[0].TheAddress;
|
||||
SETIOV(&in[inIdx], &privkey, sizeof(unsigned int));
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
else {
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
|
||||
/* msg */
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* r out */
|
||||
SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
/* s out */
|
||||
SETIOV(&out[outIdx], buf[3].TheAddress, buf[3].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_ECDSA_SIGN;
|
||||
break;
|
||||
|
||||
case CAAM_ECDSA_ECDH:
|
||||
/* when using memory in secure partition just send the address */
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* private key */
|
||||
if (args[0] == CAAM_BLACK_KEY_SM) {
|
||||
privkey = buf[1].TheAddress;
|
||||
SETIOV(&in[inIdx], &privkey, sizeof(unsigned int));
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
else {
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
|
||||
/* shared secret */
|
||||
SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_ECDSA_ECDH;
|
||||
break;
|
||||
|
||||
case CAAM_BLOB_ENCAP:
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
if (args[0] == 1) {
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length + WC_CAAM_MAC_SZ);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
else {
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
|
||||
SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
|
||||
outIdx = outIdx + 1;
|
||||
cmd = WC_CAAM_BLOB_ENCAP;
|
||||
break;
|
||||
|
||||
case CAAM_BLOB_DECAP:
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
if (args[0] == 1) {
|
||||
SETIOV(&out[outIdx], buf[2].TheAddress,
|
||||
buf[2].Length + WC_CAAM_MAC_SZ);
|
||||
outIdx = outIdx + 1;
|
||||
}
|
||||
else {
|
||||
SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
|
||||
outIdx = outIdx + 1;
|
||||
}
|
||||
|
||||
cmd = WC_CAAM_BLOB_DECAP;
|
||||
break;
|
||||
|
||||
case CAAM_AESECB:
|
||||
/* key */
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* in */
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* out */
|
||||
SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
|
||||
outIdx = outIdx + 1;
|
||||
cmd = WC_CAAM_AESECB;
|
||||
break;
|
||||
|
||||
case CAAM_AESCBC:
|
||||
/* key */
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* in */
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* iv */
|
||||
SETIOV(&in[inIdx], buf[2].TheAddress, buf[2].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* out */
|
||||
SETIOV(&out[outIdx], buf[3].TheAddress, buf[3].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
/* out updated IV */
|
||||
SETIOV(&out[outIdx], buf[4].TheAddress, buf[4].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_AESCBC;
|
||||
break;
|
||||
|
||||
case CAAM_AESCTR:
|
||||
/* key */
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* iv */
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* in */
|
||||
SETIOV(&in[inIdx], buf[2].TheAddress, buf[2].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* out */
|
||||
SETIOV(&out[outIdx], buf[3].TheAddress, buf[3].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
/* out updated IV */
|
||||
SETIOV(&out[outIdx], buf[4].TheAddress, buf[4].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_AESCTR;
|
||||
break;
|
||||
|
||||
case CAAM_AESCCM:
|
||||
/* key */
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* iv */
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* in */
|
||||
SETIOV(&in[inIdx], buf[2].TheAddress, buf[2].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* out */
|
||||
SETIOV(&out[outIdx], buf[3].TheAddress, buf[3].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
/* set TAG as input or output */
|
||||
if ((args[0] & 0xFFFF) == CAAM_ENC) {
|
||||
SETIOV(&out[outIdx], buf[4].TheAddress, buf[4].Length);
|
||||
outIdx = outIdx + 1;
|
||||
}
|
||||
else {
|
||||
SETIOV(&in[inIdx], buf[4].TheAddress, buf[4].Length);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
|
||||
/* aad */
|
||||
SETIOV(&in[inIdx], buf[5].TheAddress, buf[5].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_AESCCM;
|
||||
break;
|
||||
|
||||
case CAAM_AESGCM:
|
||||
/* key */
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* iv */
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* in */
|
||||
SETIOV(&in[inIdx], buf[2].TheAddress, buf[2].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* out */
|
||||
SETIOV(&out[outIdx], buf[3].TheAddress, buf[3].Length);
|
||||
outIdx = outIdx + 1;
|
||||
|
||||
/* set TAG as input or output */
|
||||
if ((args[0] & 0xFFFF) == CAAM_ENC) {
|
||||
SETIOV(&out[outIdx], buf[4].TheAddress, buf[4].Length);
|
||||
outIdx = outIdx + 1;
|
||||
}
|
||||
else {
|
||||
SETIOV(&in[inIdx], buf[4].TheAddress, buf[4].Length);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
|
||||
/* aad */
|
||||
SETIOV(&in[inIdx], buf[5].TheAddress, buf[5].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
cmd = WC_CAAM_AESGCM;
|
||||
break;
|
||||
|
||||
case CAAM_CMAC:
|
||||
{
|
||||
int i;
|
||||
|
||||
if (args[2] == 1) {
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length + 16);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
else {
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
}
|
||||
|
||||
SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
/* get input buffers */
|
||||
args[3] = 0;
|
||||
for (i = 2; i < sz && i < MAX_IN_IOVS; i++) {
|
||||
SETIOV(&in[inIdx], buf[i].TheAddress, buf[i].Length);
|
||||
inIdx = inIdx + 1;
|
||||
args[3] += buf[i].Length;
|
||||
}
|
||||
|
||||
SETIOV(&out[outIdx], buf[1].TheAddress, buf[1].Length);
|
||||
outIdx = outIdx + 1;
|
||||
}
|
||||
cmd = WC_CAAM_CMAC;
|
||||
break;
|
||||
|
||||
case CAAM_FIFO_S:
|
||||
SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
|
||||
inIdx = inIdx + 1;
|
||||
|
||||
SETIOV(&out[outIdx], buf[1].TheAddress, buf[1].Length + WC_CAAM_MAC_SZ);
|
||||
outIdx = outIdx + 1;
|
||||
cmd = WC_CAAM_FIFO_S;
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown/unsupported type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = wc_LockMutex(&caamMutex);
|
||||
if (ret == 0) {
|
||||
ret = devctlv(caamFd, cmd, inIdx, outIdx, in, out, NULL);
|
||||
wc_UnLockMutex(&caamMutex);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (ret == EFAULT) {
|
||||
WOLFSSL_MSG("bad address on one of the in/out buffers");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == EAGAIN && type == CAAM_ENTROPY) {
|
||||
return CAAM_WAITING;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_QNX_CAAM && (__QNX__ || __QNXNTO__) */
|
@ -0,0 +1,106 @@
|
||||
/* wolfcaam_rsa.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>
|
||||
|
||||
#if defined(WOLFSSL_CAAM) && !defined(NO_RSA)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_DEVCRYPTO_RSA)
|
||||
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
|
||||
|
||||
/* HSM lib does not support RSA with QXP board, use devcrypto instead */
|
||||
int wc_CAAM_Rsa(const byte* in, word32 inLen, byte* out, word32* outLen,
|
||||
int type, RsaKey* key, WC_RNG* rng)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
switch (type) {
|
||||
case RSA_PUBLIC_ENCRYPT:
|
||||
case RSA_PRIVATE_ENCRYPT:
|
||||
ret = wc_DevCrypto_RsaEncrypt(in, inLen, out, outLen, key, type);
|
||||
break;
|
||||
|
||||
case RSA_PUBLIC_DECRYPT:
|
||||
case RSA_PRIVATE_DECRYPT:
|
||||
ret = wc_DevCrypto_RsaDecrypt(in, inLen, out, *outLen, key, type);
|
||||
}
|
||||
(void)rng;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
int wc_CAAM_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
|
||||
{
|
||||
return wc_DevCrypto_MakeRsaKey(key, size, e, rng);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
int wc_CAAM_Rsa(const byte* in, word32 inLen, byte* out, word32* outLen,
|
||||
int type, RsaKey* key, WC_RNG* rng)
|
||||
{
|
||||
(void)in;
|
||||
(void)inLen;
|
||||
(void)out;
|
||||
(void)outLen;
|
||||
(void)type;
|
||||
(void)key;
|
||||
(void)rng;
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
int wc_CAAM_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
|
||||
{
|
||||
(void)size;
|
||||
(void)e;
|
||||
(void)key;
|
||||
(void)rng;
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
#endif
|
||||
#endif /* WOLFSSL_DEVCRYPTO_RSA */
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,129 @@
|
||||
/* wolfcaam_x25519.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>
|
||||
|
||||
#if defined(WOLFSSL_CAAM) && defined(HAVE_CURVE25519)
|
||||
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_x25519.h>
|
||||
|
||||
#if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_DEVCRYPTO_CURVE25519)
|
||||
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
|
||||
|
||||
/* HSM lib does not support Curve25519 with QXP board, use devcrypto instead */
|
||||
static int wc_CAAM_Curve25519Generic(byte* out, word32 outSz, const byte* k,
|
||||
word32 kSz, const byte* a, word32 aSz, int endian)
|
||||
{
|
||||
return wc_DevCryptoCurve25519(out, outSz, k, kSz, a, aSz, endian);
|
||||
}
|
||||
|
||||
|
||||
int wc_CAAM_MakeCurve25519Key(curve25519_key* key, int keySize, WC_RNG* rng)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (keySize != CURVE25519_KEYSIZE || rng == NULL || key == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_curve25519_make_priv(rng, keySize, key->k);
|
||||
}
|
||||
|
||||
/* create public key from private key */
|
||||
if (ret == 0) {
|
||||
static const unsigned char basePoint[CURVE25519_KEYSIZE] = {9};
|
||||
word32 outlen = (word32)keySize;
|
||||
|
||||
key->privSet = 1;
|
||||
ret = wc_CAAM_Curve25519Generic(key->p.point, outlen, key->k,
|
||||
CURVE25519_KEYSIZE, basePoint, CURVE25519_KEYSIZE,
|
||||
EC25519_LITTLE_ENDIAN);
|
||||
if (ret == 0) {
|
||||
key->pubSet = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int wc_CAAM_Curve25519(byte* out, word32* outlen, curve25519_key* k,
|
||||
curve25519_key* pubKey, int endian)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (*outlen < CURVE25519_KEYSIZE) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
*outlen = CURVE25519_KEYSIZE;
|
||||
ret = wc_CAAM_Curve25519Generic(out, *outlen, k->k, CURVE25519_KEYSIZE,
|
||||
pubKey->p.point, CURVE25519_KEYSIZE, endian);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int wc_CAAM_MakeCurve25519Key(curve25519_key* key, int keySize, WC_RNG* rng)
|
||||
{
|
||||
(void)keySize;
|
||||
(void)key;
|
||||
(void)rng;
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
int wc_CAAM_Curve25519(byte* out, word32* outlen, curve25519_key* k,
|
||||
curve25519_key* pubKey, int endian)
|
||||
{
|
||||
(void)out;
|
||||
(void)outlen;
|
||||
(void)k;
|
||||
(void)pubKey;
|
||||
(void)endian;
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
#endif /* WOLFSSL_DEVCRYPTO_CURVE25519 */
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user