Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions benchmark/bench_modules/wh_bench_mod_cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ int _benchCmacAes(whClientContext* client, whBenchOpContext* ctx, int id,
return WH_ERROR_NOSPACE;
}
}
else {
else
#endif /* WOLFHSM_CFG_TEST_POSIX */
{
in = WH_BENCH_DMA_BUFFER;
}
#endif /* WOLFHSM_CFG_TEST_POSIX */
}
else
#endif
Expand Down
10 changes: 6 additions & 4 deletions docs/src/5-Features.md
Original file line number Diff line number Diff line change
Expand Up @@ -930,9 +930,11 @@ A verify method returns `WH_ERROR_OK` on a successful verification, `WH_ERROR_NO
- `wh_Server_ImgMgrVerifyMethodEccWithSha256`: ECDSA P-256 signature over the SHA-256 hash of the image
- `wh_Server_ImgMgrVerifyMethodRsaSslWithSha256`: RSA PKCS#1 v1.5 signature over the SHA-256 hash of the image
- `wh_Server_ImgMgrVerifyMethodAesCmac`: AES-128 CMAC over the image bytes
- `wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256`: RSA-4096 verification of a wolfBoot-formatted image (see [wolfBoot Image Support](#wolfboot-image-support))
- `wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256`: RSA-4096 PKCS#1 v1.5 verification of a wolfBoot-formatted image (see [wolfBoot Image Support](#wolfboot-image-support))
- `wh_Server_ImgMgrVerifyMethodWolfBootRsaPss4096WithSha256`: RSA-4096 PSS verification of a wolfBoot-formatted image (requires `WC_RSA_PSS`)
- `wh_Server_ImgMgrVerifyMethodWolfBootEcc256WithSha256`: ECDSA P-256 verification of a wolfBoot-formatted image
- `wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256`: cert-chain-based RSA-4096 verification of a wolfBoot image
- `wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256`: cert-chain-based RSA-4096 PKCS#1 v1.5 verification of a wolfBoot image
- `wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsaPss4096WithSha256`: cert-chain-based RSA-4096 PSS verification of a wolfBoot image (requires `WC_RSA_PSS`)

Applications can supply their own verify method to support algorithms not represented in the built-in set, or to layer additional checks on top of an existing one — for example, validating a monotonic counter against a [non-volatile counter](#non-volatile-monotonic-counters) inside a wrapper verify method to add anti-rollback protection. The maximum signature size handled by the framework is `WOLFHSM_CFG_SERVER_IMG_MGR_MAX_SIG_SIZE`, whose default accommodates RSA-4096.

Expand All @@ -954,8 +956,8 @@ A default no-op action, `wh_Server_ImgMgrVerifyActionDefault`, is provided for c

wolfHSM understands the [wolfBoot](https://github.com/wolfSSL/wolfBoot) image header format natively so that a wolfHSM-equipped system can serve as the verifier for a wolfBoot-staged image without the client having to parse the header itself. Two wolfBoot image types are recognized:

- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT`: the signature is extracted from the wolfBoot TLV header and verified against a key resident in the server's keystore (identified by `keyId`). This corresponds to the standard wolfBoot signing model where the signing key is known in advance and provisioned into the HSM. Pair it with the verify method that matches how the image was signed, `wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256` or `wh_Server_ImgMgrVerifyMethodWolfBootEcc256WithSha256`. Each method rejects a header whose auth type does not match its algorithm.
- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT_CERT`: the image carries a certificate chain inside its wolfBoot header; the chain is verified against the trusted roots in NVM listed in `rootNvmIds` using the [certificate manager](#certificate-management), and the leaf certificate's public key is then used to verify the image signature. This matches the wolfBoot cert-chain mode and is the right choice when the signing key is rotated independently of the on-device trust anchor. A root list follows the [multi-root verify](#chain-verification) rules: the chain is accepted if it anchors to any listed root, and listed roots not present in NVM are skipped. The verify method returns `WH_ERROR_CERT_VERIFY` if no listed root anchors the chain, and `WH_ERROR_NOTFOUND` if none of them is in NVM. A root list also lets a device move to a new root without changing its image configuration: list both roots, provision the new one, and erase the old one once it is retired.
- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT`: the signature is extracted from the wolfBoot TLV header and verified against a key resident in the server's keystore (identified by `keyId`). This corresponds to the standard wolfBoot signing model where the signing key is known in advance and provisioned into the HSM. Pair it with the verify method that matches how the image was signed: `wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256` (wolfBoot `SIGN=RSA4096`), `wh_Server_ImgMgrVerifyMethodWolfBootRsaPss4096WithSha256` (`SIGN=RSAPSS4096`), or `wh_Server_ImgMgrVerifyMethodWolfBootEcc256WithSha256` (`SIGN=ECC256`). Each method rejects a header whose auth type does not match its algorithm.
- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT_CERT`: the image carries a certificate chain inside its wolfBoot header; the chain is verified against the trusted roots in NVM listed in `rootNvmIds` using the [certificate manager](#certificate-management), and the leaf certificate's public key is then used to verify the image signature. This matches the wolfBoot cert-chain mode and is the right choice when the signing key is rotated independently of the on-device trust anchor. Use `wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256` for images signed with `SIGN=RSA4096` and `wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsaPss4096WithSha256` for `SIGN=RSAPSS4096`. A root list follows the [multi-root verify](#chain-verification) rules: the chain is accepted if it anchors to any listed root, and listed roots not present in NVM are skipped. The verify method returns `WH_ERROR_CERT_VERIFY` if no listed root anchors the chain, and `WH_ERROR_NOTFOUND` if none of them is in NVM. A root list also lets a device move to a new root without changing its image configuration: list both roots, provision the new one, and erase the old one once it is retired.

In both cases the framework parses the header at `hdrAddr`, locates the signature TLV, validates the wolfBoot magic and public key hint, and feeds the appropriate `(image, key, signature)` triple into the wolfBoot verify method. The application's `verifyAction` is invoked exactly as for a raw image.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/8-Integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ Server mode is the right choice when the bootloader has no separate secure core

Independently of which mode wolfBoot itself is running in, a wolfHSM **server application** can verify wolfBoot-formatted images on behalf of its clients using the [image manager](5-Features.md#image-manager). The image manager understands the wolfBoot TLV header natively and exposes two image types specifically for wolfBoot images:

- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT` — verifies the image against a key resident in the server's keystore, matching wolfBoot's standard signing model. Both the RSA-4096 and the ECC P-256 wolfBoot verify methods use this type.
- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT_CERT` — verifies a certificate chain embedded in the wolfBoot header against one or more trusted roots in NVM and then uses the leaf public key to verify the image, matching wolfBoot's cert-chain signing mode.
- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT` — verifies the image against a key resident in the server's keystore, matching wolfBoot's standard signing model. The RSA-4096 (PKCS#1 v1.5 and PSS) and ECC P-256 wolfBoot verify methods use this type.
- `WH_IMG_MGR_IMG_TYPE_WOLFBOOT_CERT` — verifies a certificate chain embedded in the wolfBoot header against one or more trusted roots in NVM and then uses the leaf public key to verify the image, matching wolfBoot's cert-chain signing mode. The RSA-4096 cert chain verify methods cover both PKCS#1 v1.5 and PSS images.

The full mechanism is documented in [wolfBoot Image Support](5-Features.md#wolfboot-image-support). This allows wolfBoot and wolfHSM client/server applications to share a single image format and the same trusted roots: the same `.bin` that wolfBoot would verify locally can be verified by a wolfHSM server through the image manager, and the same root CAs provisioned on the HSM work for both flows, provided they reside in the certificate namespace (TYPE = `WH_KEYTYPE_CERT`) referenced by both the client certificate API and the image manager root list `rootNvmIds` (see [Trusted Root Storage](5-Features.md#trusted-root-storage)). A wolfBoot build that trusts several roots (`WOLFHSM_NVM_ROOT_CA_LIST`) can list the same roots in `rootNvmIds`, so both flows accept the same images.

Expand Down
4 changes: 2 additions & 2 deletions src/wh_client_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -6102,7 +6102,7 @@ int wh_Client_Cmac(whClientContext* ctx, Cmac* cmac, CmacType type,
int ret = WH_ERROR_OK;
whMessageCrypto_CmacAesState saved;

if (ctx == NULL || cmac == NULL) {
if (ctx == NULL || cmac == NULL || (in == NULL && inLen != 0)) {
return WH_ERROR_BADARGS;
}

Expand Down Expand Up @@ -6623,7 +6623,7 @@ int wh_Client_CmacDma(whClientContext* ctx, Cmac* cmac, CmacType type,
{
int ret = WH_ERROR_OK;

if (ctx == NULL || cmac == NULL) {
if (ctx == NULL || cmac == NULL || (in == NULL && inLen != 0)) {
return WH_ERROR_BADARGS;
}

Expand Down
5 changes: 3 additions & 2 deletions src/wh_client_cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,10 @@ int wh_Client_CryptoCbStd(int devId, wc_CryptoInfo* info, void* inCtx)
#ifdef WOLFSSL_CMAC
case WC_ALGO_TYPE_CMAC:
{
/* Extract info parameters */
/* Extract info parameters. Keep inSz as given so wh_Client_Cmac()
* rejects a NULL input with a length. */
const uint8_t* in = info->cmac.in;
uint32_t in_len = (in == NULL) ? 0 : info->cmac.inSz;
uint32_t in_len = info->cmac.inSz;
const uint8_t* key = info->cmac.key;
uint32_t key_len = (key == NULL) ? 0 : info->cmac.keySz;
uint8_t* outMac = info->cmac.out;
Expand Down
111 changes: 91 additions & 20 deletions src/wh_server_img_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,19 +679,23 @@ static int _wolfBootImgDecodeRsaDigestInfo(uint8_t** pInput, int inputSz)
}

/**
* Verify RSA4096 signature against a hash using PKCS#1 v1.5.
* Verify RSA4096 signature against a hash. Uses RSA-PSS when authType is
* WH_IMG_MGR_WOLFBOOT_AUTH_RSAPSS4096, otherwise PKCS#1 v1.5.
*/
static int _wolfBootImgVerifySigRsa4096(const uint8_t* sig, uint16_t sigSz,
const uint8_t* hash, uint32_t hashSz,
const uint8_t* pubkey,
uint32_t pubkeySz, int devId)
uint32_t pubkeySz, int devId,
uint8_t authType)
{
int ret;
RsaKey rsa;
uint8_t output[512]; /* RSA4096_SIG_SIZE */
uint8_t* digest_out = NULL;
word32 inOutIdx = 0;

(void)authType;

if (sigSz != 512) {
return WH_ERROR_BADARGS;
}
Expand All @@ -708,6 +712,23 @@ static int _wolfBootImgVerifySigRsa4096(const uint8_t* sig, uint16_t sigSz,
}

memcpy(output, sig, 512);

#ifdef WC_RSA_PSS
if (authType == WH_IMG_MGR_WOLFBOOT_AUTH_RSAPSS4096) {
/* Same settings as the wolfBoot sign tool: MGF1-SHA256 and a salt as
* long as the hash. Also checks the hash. */
ret = wc_RsaPSS_VerifyCheckInline(output, 512, &digest_out, hash,
hashSz, WC_HASH_TYPE_SHA256,
WC_MGF1SHA256, &rsa);
wc_FreeRsaKey(&rsa);

if (ret <= 0 || digest_out == NULL) {
return WH_ERROR_NOTVERIFIED;
}
return WH_ERROR_OK;
}
#endif /* WC_RSA_PSS */

ret = wc_RsaSSL_VerifyInline(output, 512, &digest_out, &rsa);
wc_FreeRsaKey(&rsa);

Expand Down Expand Up @@ -922,9 +943,12 @@ static int _wolfBootImgValidateAndHash(


#ifndef NO_RSA
int wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256(
whServerImgMgrContext* context, const whServerImgMgrImg* img,
const uint8_t* key, size_t keySz, const uint8_t* sig, size_t sigSz)
/* Shared body of the wolfBoot RSA4096 verify methods. authType must match the
* header and picks PKCS#1 v1.5 or PSS. */
static int _wolfBootImgVerifyRsa4096(whServerImgMgrContext* context,
const whServerImgMgrImg* img,
const uint8_t* key, size_t keySz,
uint8_t authType)
{
int ret;
uint8_t computed_hash[WC_SHA256_DIGEST_SIZE];
Expand All @@ -944,9 +968,6 @@ int wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256(
int payloadMapped = 0;
#endif

(void)sig;
(void)sigSz;

if (context == NULL || context->server == NULL || img == NULL ||
key == NULL || keySz == 0) {
return WH_ERROR_BADARGS;
Expand Down Expand Up @@ -996,7 +1017,7 @@ int wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256(
/* Validate header, compute and verify hash, extract signature */
ret = _wolfBootImgValidateAndHash(hdr, img->hdrSize, payload, payloadSize,
computed_hash, &hdr_sig, &hdr_sig_sz,
devId, WH_IMG_MGR_WOLFBOOT_AUTH_RSA4096);
devId, authType);
if (ret != WH_ERROR_OK) {
goto cleanup;
}
Expand All @@ -1013,7 +1034,7 @@ int wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256(
/* Verify RSA4096 signature */
ret = _wolfBootImgVerifySigRsa4096(hdr_sig, hdr_sig_sz, computed_hash,
WC_SHA256_DIGEST_SIZE, key,
(uint32_t)keySz, devId);
(uint32_t)keySz, devId, authType);

cleanup:
#ifdef WOLFHSM_CFG_DMA
Expand All @@ -1028,6 +1049,30 @@ int wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256(
#endif
return ret;
}

int wh_Server_ImgMgrVerifyMethodWolfBootRsa4096WithSha256(
Comment thread
AlexLanzano marked this conversation as resolved.
whServerImgMgrContext* context, const whServerImgMgrImg* img,
const uint8_t* key, size_t keySz, const uint8_t* sig, size_t sigSz)
{
(void)sig;
(void)sigSz;

return _wolfBootImgVerifyRsa4096(context, img, key, keySz,
WH_IMG_MGR_WOLFBOOT_AUTH_RSA4096);
}

#ifdef WC_RSA_PSS
int wh_Server_ImgMgrVerifyMethodWolfBootRsaPss4096WithSha256(
Comment thread
AlexLanzano marked this conversation as resolved.
whServerImgMgrContext* context, const whServerImgMgrImg* img,
const uint8_t* key, size_t keySz, const uint8_t* sig, size_t sigSz)
{
(void)sig;
(void)sigSz;

return _wolfBootImgVerifyRsa4096(context, img, key, keySz,
WH_IMG_MGR_WOLFBOOT_AUTH_RSAPSS4096);
}
#endif /* WC_RSA_PSS */
#endif /* !NO_RSA */

#ifdef HAVE_ECC
Expand Down Expand Up @@ -1236,9 +1281,12 @@ int wh_Server_ImgMgrVerifyMethodWolfBootEcc256WithSha256(
#endif /* HAVE_ECC */

#if defined(WOLFHSM_CFG_CERTIFICATE_MANAGER) && !defined(NO_RSA)
int wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256(
whServerImgMgrContext* context, const whServerImgMgrImg* img,
const uint8_t* key, size_t keySz, const uint8_t* sig, size_t sigSz)
/* Shared body of the wolfBoot RSA4096 cert chain verify methods. authType
* must match the header and picks PKCS#1 v1.5 or PSS for the image
* signature. */
static int _wolfBootImgVerifyCertChainRsa4096(whServerImgMgrContext* context,
const whServerImgMgrImg* img,
uint8_t authType)
{
int ret;
uint8_t computed_hash[WC_SHA256_DIGEST_SIZE];
Expand All @@ -1263,11 +1311,6 @@ int wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256(
int payloadMapped = 0;
#endif

(void)key;
(void)keySz;
(void)sig;
(void)sigSz;

if (context == NULL || img == NULL) {
return WH_ERROR_BADARGS;
}
Expand Down Expand Up @@ -1319,7 +1362,7 @@ int wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256(
/* Validate header, compute and verify hash, extract signature */
ret = _wolfBootImgValidateAndHash(hdr, img->hdrSize, payload, payloadSize,
computed_hash, &hdr_sig, &hdr_sig_sz,
devId, WH_IMG_MGR_WOLFBOOT_AUTH_RSA4096);
devId, authType);
if (ret != WH_ERROR_OK) {
goto cleanup;
}
Expand Down Expand Up @@ -1359,7 +1402,7 @@ int wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256(
/* Verify RSA4096 signature using leaf pubkey */
ret = _wolfBootImgVerifySigRsa4096(hdr_sig, hdr_sig_sz, computed_hash,
WC_SHA256_DIGEST_SIZE, leafKeyBuf,
leafKeyMeta->len, devId);
leafKeyMeta->len, devId, authType);

evict_cleanup:
/* Evict cached leaf key */
Expand All @@ -1378,6 +1421,34 @@ int wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256(
#endif
return ret;
}

int wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsa4096WithSha256(
Comment thread
AlexLanzano marked this conversation as resolved.
whServerImgMgrContext* context, const whServerImgMgrImg* img,
const uint8_t* key, size_t keySz, const uint8_t* sig, size_t sigSz)
{
(void)key;
(void)keySz;
(void)sig;
(void)sigSz;

return _wolfBootImgVerifyCertChainRsa4096(context, img,
WH_IMG_MGR_WOLFBOOT_AUTH_RSA4096);
}

#ifdef WC_RSA_PSS
int wh_Server_ImgMgrVerifyMethodWolfBootCertChainRsaPss4096WithSha256(
Comment thread
AlexLanzano marked this conversation as resolved.
whServerImgMgrContext* context, const whServerImgMgrImg* img,
const uint8_t* key, size_t keySz, const uint8_t* sig, size_t sigSz)
{
(void)key;
(void)keySz;
(void)sig;
(void)sigSz;

return _wolfBootImgVerifyCertChainRsa4096(
context, img, WH_IMG_MGR_WOLFBOOT_AUTH_RSAPSS4096);
}
#endif /* WC_RSA_PSS */
#endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER && !NO_RSA */

#endif /* !NO_RSA || HAVE_ECC */
Expand Down
Loading
Loading