wolfssl-examples/wisekey_vaultic/wisekey_vaultic.c

482 lines
12 KiB
C

/*
* wisekey_vaultic.c
*
* Copyright (C) 2023 wolfSSL Inc.
*
* 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
*/
#include "wolfssl/wolfcrypt/cryptocb.h"
#include "wolfssl/wolfcrypt/error-crypt.h"
#include "wolfssl/wolfcrypt/wc_port.h"
#include "wolfssl/wolfcrypt/types.h"
#include <stdlib.h> /* For NULL */
#include <errno.h> /* For Exxx */
#include <string.h> /* For memset/cpy */
#include "user_settings.h"
#include "wisekey_vaultic.h"
/* Include Wisekey's devkit header */
#include "vaultic_tls.h"
#include "vaultic_config.h"
#include "vaultic_common.h"
#include "vaultic_api.h"
#include "vaultic_structs.h"
/* Forward declarations */
static int HandlePkCallback(int devId, wc_CryptoInfo* info, void* ctx);
static int HandleHashCallback(int devId, wc_CryptoInfo* info, void* ctx);
static int HandleCipherCallback(int devId, wc_CryptoInfo* info, void* ctx);
int WisekeyVaultIC_Init(wkvicContext *c)
{
int rc=0;
if(!c) {
return -EINVAL;
}
rc =vlt_tls_init();
if(rc!=0) {
return rc;
}
memset(c, 0, sizeof(*c));
return 0;
}
int WisekeyVaultIC_Cleanup(wkvicContext *c)
{
if(!c) {
return -EINVAL;
}
memset(c, 0, sizeof(*c));
return vlt_tls_close();
}
int WisekeyVaultIC_CryptoDevCb(int devId,
wc_CryptoInfo* info,
void* ctx)
{
wkvicContext *c=(wkvicContext*)ctx;
int rc = CRYPTOCB_UNAVAILABLE;
(void)devId;
if(!info) {
/* Invalid info or context */
return rc;
}
switch(info->algo_type) {
case WC_ALGO_TYPE_NONE:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb NONE:\n");
#endif
/* Nothing to do */
break;
case WC_ALGO_TYPE_HASH:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb HASH: Type:%d\n", info->hash.type);
#endif
#if !defined(NO_SHA) || !defined(NO_SHA256)
/* Perform a hash */
rc = HandleHashCallback(devId, info, ctx);
#endif
break;
case WC_ALGO_TYPE_CIPHER:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb CIPHER: Type:%d\n", info->cipher.type);
#endif
#if !defined(NO_AES)
/* Perform a symmetric cipher */
rc = HandleCipherCallback(devId, info, ctx);
#endif
break;
case WC_ALGO_TYPE_PK:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb PK: Type:%d\n", info->pk.type);
#endif
#if !defined(NO_RSA) || defined(HAVE_ECC)
/* Perform a PKI operation */
rc = HandlePkCallback(devId,info,ctx);
#endif /* !defined(NO_RSA) || defined(HAVE_ECC) */
break;
case WC_ALGO_TYPE_RNG:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb RNG: Out:%p Sz:%d\n", info->rng.out, info->rng.sz);
#endif
#if !defined(WC_NO_RNG)
/* Put info->rng.sz random bytes into info->rng.out*/
/* TODO rc = VaultIC_Random(); */
rc = CRYPTOCB_UNAVAILABLE;
#endif
break;
case WC_ALGO_TYPE_SEED:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb SEED: Seed:%p Sz:%d\n", info->seed.seed,
info->seed.sz);
#endif
#if !defined(WC_NO_RNG)
/* Get info->seed.sz seed bytes from info->seed.seed*/
/* TODO rc = VaultIC_Seed(); */
#endif
break;
case WC_ALGO_TYPE_HMAC:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb HMAC:\n");
#endif
break;
case WC_ALGO_TYPE_CMAC:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb CMAC:\n");
#endif
break;
default:
#if defined(DEBUG_VAULTIC)
printf(" CryptoDevCb UNKNOWN\n");
#endif
break;
}
return rc;
}
static int HandlePkCallback(int devId, wc_CryptoInfo* info, void* ctx)
{
int rc = CRYPTOCB_UNAVAILABLE;
switch(info->pk.type) {
case WC_PK_TYPE_NONE:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback NONE\n");
#endif
break;
case WC_PK_TYPE_RSA:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback RSA\n");
#endif
break;
case WC_PK_TYPE_DH:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback DH\n");
#endif
break;
case WC_PK_TYPE_ECDH:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback ECDH\n");
#endif
break;
case WC_PK_TYPE_ECDSA_SIGN:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback ECDSA_SIGN\n");
#endif
break;
case WC_PK_TYPE_ECDSA_VERIFY:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback ECDSA_VERIFY\n");
#endif
break;
case WC_PK_TYPE_ED25519_SIGN:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback ED25519_SIGN\n");
#endif
break;
case WC_PK_TYPE_CURVE25519:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback CURVE25519\n");
#endif
break;
case WC_PK_TYPE_RSA_KEYGEN:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback RSA_KEYGEN\n");
#endif
break;
case WC_PK_TYPE_EC_KEYGEN:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback EC_KEYGEN\n");
#endif
break;
case WC_PK_TYPE_RSA_CHECK_PRIV_KEY:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback RSA_CHECK_PRIV_KEY\n");
#endif
break;
case WC_PK_TYPE_EC_CHECK_PRIV_KEY:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback EC_CHECK_PRIV_KEY\n");
#endif
break;
case WC_PK_TYPE_ED448:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback ED448\n");
#endif
break;
case WC_PK_TYPE_CURVE448:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback CRUVE448\n");
#endif
break;
case WC_PK_TYPE_ED25519_VERIFY:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback ED25519_VERIFY\n");
#endif
break;
case WC_PK_TYPE_ED25519_KEYGEN:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback ED25519_KEYGEN\n");
#endif
break;
case WC_PK_TYPE_CURVE25519_KEYGEN:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback CURVE25519_KEYGEN\n");
#endif
break;
case WC_PK_TYPE_RSA_GET_SIZE:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback RSA_GET_SIZE\n");
#endif
break;
default:
#if defined(DEBUG_VAULTIC)
printf(" HandlePkCallback UNKNOWN\n");
#endif
break;
}
return rc;
}
static int HandleHashCallback(int devId, wc_CryptoInfo* info, void* ctx)
{
int rc = CRYPTOCB_UNAVAILABLE;
int finalize=0;
/* Finalize sha? */
if((info->hash.in == NULL) && (info->hash.inSz==0)) {
finalize=1;
}
switch(info->hash.type) {
case WC_HASH_TYPE_NONE:
#if defined(DEBUG_VAULTIC)
printf(" HandleHashCallback NONE\n");
#endif
break;
case WC_HASH_TYPE_SHA:
#if defined(DEBUG_VAULTIC)
printf(" HandleHashCallback SHA\n");
#endif
break;
case WC_HASH_TYPE_SHA224:
#if defined(DEBUG_VAULTIC)
printf(" HandleHashCallback SHA224\n");
#endif
break;
case WC_HASH_TYPE_SHA256:
#if defined(DEBUG_VAULTIC)
printf(" HandleHashCallback SHA256\n");
#endif
break;
case WC_HASH_TYPE_SHA384:
#if defined(DEBUG_VAULTIC)
printf(" HandleHashCallback SHA384\n");
#endif
break;
case WC_HASH_TYPE_SHA512:
#if defined(DEBUG_VAULTIC)
printf(" HandleHashCallback SHA512\n");
#endif
break;
default:
break;
}
return rc;
}
static int HandleCipherCallback(int devId, wc_CryptoInfo* info, void* ctx)
{
wkvicContext *c=(wkvicContext*)ctx;
int rc = CRYPTOCB_UNAVAILABLE;
switch(info->cipher.type) {
case WC_CIPHER_NONE:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback NONE\n");
#endif
break;
case WC_CIPHER_AES:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES\n");
#endif
break;
case WC_CIPHER_AES_CBC:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES_CBC\n");
#endif
{
Aes* aes=info->cipher.aescbc.aes;
int encrypt=info->cipher.enc;
VLT_U32 out_len=0;
if(!aes) break;
/* Support AES128 for now */
if(aes->keylen != AES_128_KEY_SIZE) break;
unsigned int blocks = info->cipher.aescbc.sz / AES_BLOCK_SIZE;
if(blocks == 0) break;
/* Allow all privileges */
VLT_FILE_PRIVILEGES keyPrivileges = {
.u8Read=0xFF,
.u8Write=0xFF,
.u8Delete=0xFF,
.u8Execute=0xFF,
};
VLT_KEY_OBJECT tmpAesKey= {
.enKeyID=VLT_KEY_AES_128,
.data.SecretKey.u8Mask=0,
.data.SecretKey.u16KeyLength=aes->keylen,
.data.SecretKey.pu8Key=(VLT_PU8)aes->devKey,
};
/* Try to delete the tmp aes key. Ignore errors here */
VltDeleteKey(
WISEKEY_VAULTIC_WOLFSSL_GRPID,
WISEKEY_VAULTIC_TMPAES_KEYID);
/* Putkey aes->devKey, aes->keylen */
VltPutKey(
WISEKEY_VAULTIC_WOLFSSL_GRPID,
WISEKEY_VAULTIC_TMPAES_KEYID,
&keyPrivileges,
&tmpAesKey);
/* Initialize Algo for AES-CBC */
VLT_ALGO_PARAMS aescbc_algo_params = {
.u8AlgoID=VLT_ALG_CIP_AES,
.data.SymCipher.enMode= BLOCK_MODE_CBC,
.data.SymCipher.enPadding= PADDING_NONE,
.data.SymCipher.u8IvLength= AES_BLOCK_SIZE,
.data.SymCipher.u8Iv={0},
};
memcpy(aescbc_algo_params.data.SymCipher.u8Iv,aes->reg,
AES_BLOCK_SIZE);
/* Perform encrypt/decrypt*/
if(encrypt) {
VltInitializeAlgorithm(
WISEKEY_VAULTIC_WOLFSSL_GRPID,
WISEKEY_VAULTIC_TMPAES_KEYID,
VLT_ENCRYPT_MODE,
&aescbc_algo_params);
VltEncrypt(info->cipher.aescbc.sz, info->cipher.aescbc.in,
&out_len,
info->cipher.aescbc.sz, info->cipher.aescbc.out);
const byte *last_block = info->cipher.aescbc.out + (blocks -1) * AES_BLOCK_SIZE;
memcpy(aes->reg, last_block, AES_BLOCK_SIZE);
} else {
VltInitializeAlgorithm(
WISEKEY_VAULTIC_WOLFSSL_GRPID,
WISEKEY_VAULTIC_TMPAES_KEYID,
VLT_DECRYPT_MODE,&aescbc_algo_params);
VltDecrypt(info->cipher.aescbc.sz, info->cipher.aescbc.in,
&out_len,
info->cipher.aescbc.sz, info->cipher.aescbc.out);
const byte *last_block = info->cipher.aescbc.in + (blocks -1) * AES_BLOCK_SIZE;
memcpy(aes->reg, last_block, AES_BLOCK_SIZE);
}
/* Delete the tmp aes key */
VltDeleteKey(
WISEKEY_VAULTIC_WOLFSSL_GRPID,
WISEKEY_VAULTIC_TMPAES_KEYID);
/* Update return value to indicate success */
rc=0;
}
break;
case WC_CIPHER_AES_GCM:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES_GCM\n");
#endif
break;
case WC_CIPHER_AES_CTR:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES_CTR\n");
#endif
break;
case WC_CIPHER_AES_XTS:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES_XTS\n");
#endif
break;
case WC_CIPHER_AES_CFB:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES_CFB\n");
#endif
break;
case WC_CIPHER_AES_CCM:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES_CCM\n");
#endif
break;
case WC_CIPHER_AES_ECB:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback AES_ECB\n");
#endif
break;
default:
#if defined(DEBUG_VAULTIC)
printf(" HandleCipherCallback UNKNOWN\n");
#endif
break;
}
return rc;
}