Skip to content
Merged
8 changes: 8 additions & 0 deletions include/wolfcose/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,14 @@ extern "C" {
#error "wolfCOSE RSA-PSS key validation requires WOLFSSL_EXPORT_INT"
#endif

/* The local ECDSA signing path converts a wolfCrypt DER signature to the
* fixed-width COSE representation. NO_ASN is supported for verification
* builds only. */
#if defined(NO_ASN) && defined(WOLFCOSE_HAVE_ECDSA) && \
(defined(WOLFCOSE_SIGN1_SIGN) || defined(WOLFCOSE_SIGN_SIGN))
#error "wolfCOSE ECDSA signing requires ASN support"
#endif

/* Optional RFC 6979 deterministic ECDSA signing. */
#if defined(WOLFCOSE_ENABLE_DETERMINISTIC_ECDSA) && \
defined(WOLFCOSE_HAVE_ECDSA) && \
Expand Down
6 changes: 6 additions & 0 deletions src/wolfcose_encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ int wc_CoseEncrypt_Encrypt(const WOLFCOSE_RECIPIENT* recipients,
(iv == NULL) || (ivLen == 0u)) {
ret = WOLFCOSE_E_INVALID_ARG;
}
if ((ret == WOLFCOSE_SUCCESS) && (detachedPayload == NULL) &&
(detachedLen != 0u)) {
ret = WOLFCOSE_E_INVALID_ARG;
}

#ifdef WOLFCOSE_CHECK_WORD32_LEN
if ((ret == WOLFCOSE_SUCCESS) &&
Expand Down Expand Up @@ -649,6 +653,7 @@ int wc_CoseEncrypt_Encrypt(const WOLFCOSE_RECIPIENT* recipients,
#if defined(WOLFCOSE_HAVE_AESGCM) || defined(WOLFCOSE_HAVE_AESCCM)
if (aesInited != 0) {
(void)wc_AesFree(&aes);
(void)wolfCose_ForceZero(&aes, sizeof(aes));
}
#endif
#if defined(WOLFCOSE_KEY_WRAP)
Expand Down Expand Up @@ -1263,6 +1268,7 @@ int wc_CoseEncrypt_Decrypt(const WOLFCOSE_RECIPIENT* recipient,
#if defined(WOLFCOSE_HAVE_AESGCM) || defined(WOLFCOSE_HAVE_AESCCM)
if (aesInited != 0) {
(void)wc_AesFree(&aes);
(void)wolfCose_ForceZero(&aes, sizeof(aes));
}
#endif
#if defined(WOLFCOSE_KEY_WRAP)
Expand Down
2 changes: 2 additions & 0 deletions src/wolfcose_encrypt0.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ int wc_CoseEncrypt0_Encrypt(const WOLFCOSE_KEY* key, int32_t alg,
#if defined(WOLFCOSE_HAVE_AESGCM) || defined(WOLFCOSE_HAVE_AESCCM)
if (aesInited != 0) {
(void)wc_AesFree(&aes);
(void)wolfCose_ForceZero(&aes, sizeof(aes));
}
#endif
if (scratch != NULL) {
Expand Down Expand Up @@ -726,6 +727,7 @@ int wc_CoseEncrypt0_Decrypt(const WOLFCOSE_KEY* key,
#if defined(WOLFCOSE_HAVE_AESGCM) || defined(WOLFCOSE_HAVE_AESCCM)
if (aesInited != 0) {
(void)wc_AesFree(&aes);
(void)wolfCose_ForceZero(&aes, sizeof(aes));
}
#endif
if (scratch != NULL) {
Expand Down
30 changes: 21 additions & 9 deletions src/wolfcose_hdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,20 @@ int wolfCose_InInt32Range(int64_t val)
static uint32_t wolfCose_LabelBit(int64_t label)
{
uint32_t bit;
uint32_t shift;
int64_t shift64;
uint32_t shift = 32u;

if ((label >= 1) && (label <= 16)) {
shift64 = label;
shift64--;
shift = (uint32_t)shift64;
bit = ((uint32_t)1u) << shift;
shift = (uint32_t)label;
shift--;
}
else if ((label <= -1) && (label >= -16)) {
shift64 = -label;
shift = (uint32_t)shift64;
shift = (uint32_t)(-label);
shift += 15u;
}
else {
/* No tracked bit. */
}
if (shift < 32u) {
bit = ((uint32_t)1u) << shift;
}
else {
Expand Down Expand Up @@ -221,12 +222,17 @@ int wolfCose_DecodeProtectedHdr(const uint8_t* data, size_t dataLen,
if ((hdr == NULL) || (hdrState == NULL)) {
ret = WOLFCOSE_E_INVALID_ARG;
}
else if ((data == NULL) || (dataLen == 0u)) {
else if ((data == NULL) && (dataLen != 0u)) {
ret = WOLFCOSE_E_INVALID_ARG;
}
else if (dataLen == 0u) {
/* Empty protected header is valid */
wolfCose_HdrStateInit(hdrState);
ret = WOLFCOSE_SUCCESS;
}
else {
uint8_t contentTypeUnderstood = 0u;

wolfCose_HdrStateInit(hdrState);
ctx.cbuf = data;
ctx.bufSz = dataLen;
Expand Down Expand Up @@ -317,6 +323,7 @@ int wolfCose_DecodeProtectedHdr(const uint8_t* data, size_t dataLen,
}
if (ret == WOLFCOSE_SUCCESS) {
hdr->contentType = (int32_t)contentTypeVal;
contentTypeUnderstood = 1u;
}
}
}
Expand Down Expand Up @@ -366,6 +373,11 @@ int wolfCose_DecodeProtectedHdr(const uint8_t* data, size_t dataLen,
((critLabels & ~hdrState->labelBits) != 0u)) {
ret = WOLFCOSE_E_COSE_BAD_HDR;
}
if ((ret == WOLFCOSE_SUCCESS) &&
((critLabels & wolfCose_LabelBit(WOLFCOSE_HDR_CONTENT_TYPE)) !=
0u) && (contentTypeUnderstood == 0u)) {
ret = WOLFCOSE_E_COSE_BAD_HDR;
}

/* IV and Partial IV are mutually exclusive. */
if ((ret == WOLFCOSE_SUCCESS) &&
Expand Down
15 changes: 4 additions & 11 deletions src/wolfcose_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,17 +624,10 @@ int wc_CoseMac_Verify(const WOLFCOSE_RECIPIENT* recipient,
ret = WOLFCOSE_E_COSE_BAD_ALG;
}

/* COSE_Mac is direct-keyed here and the recipient algorithm is mandatory. */
if (ret == WOLFCOSE_SUCCESS) {
if (recipientAlgId == WOLFCOSE_ALG_UNSET) {
ret = WOLFCOSE_E_COSE_BAD_ALG;
}
else if (recipientAlgId != WOLFCOSE_ALG_DIRECT) {
ret = WOLFCOSE_E_UNSUPPORTED;
}
else {
/* No action required */
}
/* COSE_Mac is direct-keyed here. */
if ((ret == WOLFCOSE_SUCCESS) &&
(recipientAlgId != WOLFCOSE_ALG_DIRECT)) {
ret = WOLFCOSE_E_UNSUPPORTED;
}
if (ret == WOLFCOSE_SUCCESS) {
if ((recipientValueIsNull == 0) && (recipientValueLen != 0u)) {
Expand Down
1 change: 1 addition & 0 deletions src/wolfcose_mac0.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ int wolfCose_AesCbcMac(const uint8_t* key, size_t keyLen,
/* Cleanup: always executed */
if (aesInited != 0) {
(void)wc_AesFree(&aes);
(void)wolfCose_ForceZero(&aes, sizeof(aes));
}
(void)wolfCose_ForceZero(inBlock, sizeof(inBlock));
(void)wolfCose_ForceZero(outBlock, sizeof(outBlock));
Expand Down
10 changes: 10 additions & 0 deletions tests/test_cose.c
Original file line number Diff line number Diff line change
Expand Up @@ -18098,6 +18098,10 @@ static void test_cose_protected_hdr_crit(void)
uint8_t critMissing[] = {0xA2u, 0x01u, 0x26u, 0x02u, 0x81u, 0x05u};
/* {1: -7, 2: []} : crit is an empty array -> RFC 9052 rejects */
uint8_t critEmpty[] = {0xA2u, 0x01u, 0x26u, 0x02u, 0x80u};
/* {2: [3], 3: "x"} : critical tstr content type is not understood */
uint8_t critTstrContentType[] = {
0xA2u, 0x02u, 0x81u, 0x03u, 0x03u, 0x61u, 'x'
};

TEST_LOG(" [Protected Header: crit]\n");
XMEMSET(&hdr, 0, sizeof(hdr));
Expand All @@ -18123,6 +18127,12 @@ static void test_cose_protected_hdr_crit(void)
&hdrState);
TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR,
"DecodeProtectedHdr crit empty array");

XMEMSET(&hdr, 0, sizeof(hdr));
ret = wolfCose_DecodeProtectedHdr(critTstrContentType,
sizeof(critTstrContentType), &hdr, &hdrState);
TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR,
"DecodeProtectedHdr rejects critical tstr content-type");
}

static void test_cose_cross_bucket_dup(void)
Expand Down
Loading