From cf7582e7cf3e49cc680814e1bc10fd0bd1bfbe24 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 8 Sep 2026 15:39:09 -0700 Subject: [PATCH 1/8] F-11113 - Reject protected headers for AES Key Wrap --- src/wolfcose_encrypt.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wolfcose_encrypt.c b/src/wolfcose_encrypt.c index f2c02e7..58327ab 100644 --- a/src/wolfcose_encrypt.c +++ b/src/wolfcose_encrypt.c @@ -982,6 +982,16 @@ int wc_CoseEncrypt_Decrypt(const WOLFCOSE_RECIPIENT* recipient, } } +#if defined(WOLFCOSE_KEY_WRAP) + /* RFC 9053 Section 6.2.1 requires an empty protected header bucket for + * AES Key Wrap recipients. */ + if ((ret == WOLFCOSE_SUCCESS) && + (wolfCose_IsKeyWrapAlg(recipientAlgId) != 0) && + (recipientProtectedLen != 0u)) { + ret = WOLFCOSE_E_COSE_BAD_HDR; + } +#endif + #if defined(WOLFCOSE_ECDH_ES_DIRECT) && defined(HAVE_ECC) && \ defined(HAVE_HKDF) /* The ECDH parser must have consumed an ephemeral key before the merged From 57ae10f48dd3fbde2133d0a6cf2ba4001a8c64c0 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 8 Sep 2026 16:05:43 -0700 Subject: [PATCH 2/8] F-12159 - Reject protected headers for Direct recipients --- src/wolfcose_encrypt.c | 8 ++++++++ src/wolfcose_mac.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/src/wolfcose_encrypt.c b/src/wolfcose_encrypt.c index 58327ab..0cce19d 100644 --- a/src/wolfcose_encrypt.c +++ b/src/wolfcose_encrypt.c @@ -956,6 +956,14 @@ int wc_CoseEncrypt_Decrypt(const WOLFCOSE_RECIPIENT* recipient, ret = wolfCose_UpdateRecipientMode(recipientAlgId, &recipientMode); } + /* RFC 9053 Section 6.1 requires an empty protected header bucket for + * Direct recipients. */ + if ((ret == WOLFCOSE_SUCCESS) && + (recipientAlgId == WOLFCOSE_ALG_DIRECT) && + (recipientProtectedLen != 0u)) { + ret = WOLFCOSE_E_COSE_BAD_HDR; + } + /* Classify the recipient key-management algorithm. Only direct, ECDH-ES * direct, and AES key wrap are supported; reject anything else instead of * silently treating it as direct-key decryption. */ diff --git a/src/wolfcose_mac.c b/src/wolfcose_mac.c index e476036..0bc32ce 100644 --- a/src/wolfcose_mac.c +++ b/src/wolfcose_mac.c @@ -571,6 +571,13 @@ int wc_CoseMac_Verify(const WOLFCOSE_RECIPIENT* recipient, ret = wolfCose_UpdateRecipientMode(recipientAlgId, &recipientMode); } + /* RFC 9053 Section 6.1 requires an empty protected header bucket for + * Direct recipients. */ + if ((ret == WOLFCOSE_SUCCESS) && + (recipientAlgId == WOLFCOSE_ALG_DIRECT) && + (recipProtLen != 0u)) { + ret = WOLFCOSE_E_COSE_BAD_HDR; + } /* Parse the recipient ciphertext before classifying its algorithm. */ if (ret == WOLFCOSE_SUCCESS) { recipientValueIsNull = 0; From 27341422408be88f96c398b1d30d3e824089874e Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 8 Sep 2026 16:32:10 -0700 Subject: [PATCH 3/8] F-12949 - Validate skipped Direct recipient value --- src/wolfcose_hdr.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/wolfcose_hdr.c b/src/wolfcose_hdr.c index 93d3227..3ac5c09 100644 --- a/src/wolfcose_hdr.c +++ b/src/wolfcose_hdr.c @@ -636,7 +636,31 @@ static int wolfCose_DecodeSkippedHeaderEntry(WOLFCOSE_CBOR_CTX* ctx, ret = wolfCose_DecodeSkippedHdrAlg(ctx, alg, &algFound); } if ((ret == WOLFCOSE_SUCCESS) && (alg != NULL)) { - ret = wc_CBOR_Skip(ctx); + if (*alg == WOLFCOSE_ALG_DIRECT) { + WOLFCOSE_CBOR_ITEM item; + int recipientValueIsNull = 0; + + if ((ctx->idx < ctx->bufSz) && + (ctx->cbuf[ctx->idx] == WOLFCOSE_CBOR_NULL)) { + recipientValueIsNull = 1; + } + ret = wolfCose_CBOR_DecodeHead(ctx, &item); + if ((ret == WOLFCOSE_SUCCESS) && + (recipientValueIsNull == 0) && + (item.majorType != WOLFCOSE_CBOR_BSTR)) { + ret = WOLFCOSE_E_CBOR_TYPE; + } + else if ((ret == WOLFCOSE_SUCCESS) && + (recipientValueIsNull == 0) && (item.dataLen != 0u)) { + ret = WOLFCOSE_E_CBOR_MALFORMED; + } + else { + /* No action required */ + } + } + else { + ret = wc_CBOR_Skip(ctx); + } } return ret; From 9552c4205d65eb3ceb0b6cb58d56806b1c1c3b6c Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 8 Sep 2026 16:36:32 -0700 Subject: [PATCH 4/8] F-12950 - Reject protected skipped Direct recipients --- src/wolfcose_hdr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wolfcose_hdr.c b/src/wolfcose_hdr.c index 3ac5c09..54184ae 100644 --- a/src/wolfcose_hdr.c +++ b/src/wolfcose_hdr.c @@ -635,6 +635,12 @@ static int wolfCose_DecodeSkippedHeaderEntry(WOLFCOSE_CBOR_CTX* ctx, if ((ret == WOLFCOSE_SUCCESS) && (alg != NULL)) { ret = wolfCose_DecodeSkippedHdrAlg(ctx, alg, &algFound); } + /* RFC 9053 Section 6.1 requires an empty protected header bucket for + * Direct recipients. */ + if ((ret == WOLFCOSE_SUCCESS) && (alg != NULL) && + (*alg == WOLFCOSE_ALG_DIRECT) && (protectedLen != 0u)) { + ret = WOLFCOSE_E_COSE_BAD_HDR; + } if ((ret == WOLFCOSE_SUCCESS) && (alg != NULL)) { if (*alg == WOLFCOSE_ALG_DIRECT) { WOLFCOSE_CBOR_ITEM item; From 3f7844194ce00991e124faba8d2f58609c9659a5 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 8 Sep 2026 16:40:25 -0700 Subject: [PATCH 5/8] F-12951 - Reject nested skipped Direct recipients --- src/wolfcose_hdr.c | 4 ++++ tests/test_cose.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/wolfcose_hdr.c b/src/wolfcose_hdr.c index 54184ae..063b913 100644 --- a/src/wolfcose_hdr.c +++ b/src/wolfcose_hdr.c @@ -709,6 +709,10 @@ int wolfCose_DecodeSkippedRecipient(WOLFCOSE_CBOR_CTX* ctx, ret = wolfCose_DecodeSkippedHeaderEntry(ctx, 4u, &arrayCount, &decodedAlg); remaining--; + if ((ret == WOLFCOSE_SUCCESS) && (arrayCount == 4u) && + (decodedAlg == WOLFCOSE_ALG_DIRECT)) { + ret = WOLFCOSE_E_COSE_BAD_HDR; + } if ((ret == WOLFCOSE_SUCCESS) && (firstRecipient != 0)) { *recipientAlg = decodedAlg; firstRecipient = 0; diff --git a/tests/test_cose.c b/tests/test_cose.c index 2a4743d..0a512fe 100644 --- a/tests/test_cose.c +++ b/tests/test_cose.c @@ -17302,8 +17302,8 @@ static void test_cose_mac_dup_recipient_unprot_hdr(void) 0x04u, 0x41u, 0x01u, 0x04u, 0x41u, 0x02u, 0x40u }; - /* Valid four-element recipients appear on both sides of the selected - * recipient. Their nested direct recipients must also be decoded. */ + /* Four-element Direct recipients appear on both sides of the selected + * recipient. Neither may contain nested recipients. */ uint8_t nestedSiblings[] = { 0x85u, 0x43u, 0xA1u, 0x01u, 0x05u, 0xA0u, 0x41u, 0x78u, 0x58u, 0x20u, @@ -17352,8 +17352,8 @@ static void test_cose_mac_dup_recipient_unprot_hdr(void) ret = wc_CoseMac_Verify(&recipient, 1, nestedSiblings, sizeof(nestedSiblings), NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, &payload, &payloadLen); - TEST_ASSERT(ret == WOLFCOSE_E_MAC_FAIL, - "nested unselected recipients accepted (mac)"); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, + "nested skipped Direct recipient rejected (mac)"); ret = wc_CoseMac_Verify(&recipient, 1, tstrSibling, sizeof(tstrSibling), NULL, 0, NULL, 0, @@ -17463,8 +17463,8 @@ static void test_cose_encrypt_dup_recipient_unprot_hdr(void) 0x04u, 0x41u, 0x01u, 0x04u, 0x41u, 0x02u, 0x40u }; - /* Valid four-element recipients appear on both sides of the selected - * recipient. Their nested direct recipients must also be decoded. */ + /* Four-element Direct recipients appear on both sides of the selected + * recipient. Neither may contain nested recipients. */ uint8_t nestedSiblings[] = { 0x84u, 0x43u, 0xA1u, 0x01u, 0x01u, 0xA1u, 0x05u, 0x4Cu, @@ -17517,8 +17517,8 @@ static void test_cose_encrypt_dup_recipient_unprot_hdr(void) sizeof(nestedSiblings), NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, plaintext, sizeof(plaintext), &plaintextLen); - TEST_ASSERT(ret == WOLFCOSE_E_COSE_DECRYPT_FAIL, - "nested unselected recipients accepted (encrypt)"); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, + "nested skipped Direct recipient rejected (encrypt)"); ret = wc_CoseEncrypt_Decrypt(&recipient, 1, tstrSibling, sizeof(tstrSibling), NULL, 0, NULL, 0, From c866a54b1994c9dfb931d0394ad95fc92eb94396 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Wed, 9 Sep 2026 15:33:57 -0700 Subject: [PATCH 6/8] Harden direct recipient validation --- src/wolfcose_encrypt.c | 6 ++++++ src/wolfcose_hdr.c | 15 +++------------ src/wolfcose_mac.c | 11 ++++++++++- tests/test_cose.c | 43 ++++++++++++++++++++++++++++++++---------- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/wolfcose_encrypt.c b/src/wolfcose_encrypt.c index 0cce19d..ee93b80 100644 --- a/src/wolfcose_encrypt.c +++ b/src/wolfcose_encrypt.c @@ -1061,6 +1061,12 @@ int wc_CoseEncrypt_Decrypt(const WOLFCOSE_RECIPIENT* recipient, } ret = wolfCose_CBOR_DecodeHead(&ctx, &item); if ((ret == WOLFCOSE_SUCCESS) && + (recipientAlgId == WOLFCOSE_ALG_DIRECT) && + ((item.majorType != WOLFCOSE_CBOR_BSTR) || + (item.dataLen != 0u))) { + ret = WOLFCOSE_E_COSE_BAD_HDR; + } + else if ((ret == WOLFCOSE_SUCCESS) && (recipientValueIsNull == 0) && (item.majorType != WOLFCOSE_CBOR_BSTR)) { ret = WOLFCOSE_E_CBOR_TYPE; diff --git a/src/wolfcose_hdr.c b/src/wolfcose_hdr.c index 063b913..79e1234 100644 --- a/src/wolfcose_hdr.c +++ b/src/wolfcose_hdr.c @@ -644,21 +644,12 @@ static int wolfCose_DecodeSkippedHeaderEntry(WOLFCOSE_CBOR_CTX* ctx, if ((ret == WOLFCOSE_SUCCESS) && (alg != NULL)) { if (*alg == WOLFCOSE_ALG_DIRECT) { WOLFCOSE_CBOR_ITEM item; - int recipientValueIsNull = 0; - if ((ctx->idx < ctx->bufSz) && - (ctx->cbuf[ctx->idx] == WOLFCOSE_CBOR_NULL)) { - recipientValueIsNull = 1; - } ret = wolfCose_CBOR_DecodeHead(ctx, &item); if ((ret == WOLFCOSE_SUCCESS) && - (recipientValueIsNull == 0) && - (item.majorType != WOLFCOSE_CBOR_BSTR)) { - ret = WOLFCOSE_E_CBOR_TYPE; - } - else if ((ret == WOLFCOSE_SUCCESS) && - (recipientValueIsNull == 0) && (item.dataLen != 0u)) { - ret = WOLFCOSE_E_CBOR_MALFORMED; + ((item.majorType != WOLFCOSE_CBOR_BSTR) || + (item.dataLen != 0u))) { + ret = WOLFCOSE_E_COSE_BAD_HDR; } else { /* No action required */ diff --git a/src/wolfcose_mac.c b/src/wolfcose_mac.c index 0bc32ce..27dd7fa 100644 --- a/src/wolfcose_mac.c +++ b/src/wolfcose_mac.c @@ -587,7 +587,13 @@ int wc_CoseMac_Verify(const WOLFCOSE_RECIPIENT* recipient, } ret = wolfCose_CBOR_DecodeHead(&ctx, &item); } - if (ret == WOLFCOSE_SUCCESS) { + if ((ret == WOLFCOSE_SUCCESS) && + (recipientAlgId == WOLFCOSE_ALG_DIRECT) && + ((item.majorType != WOLFCOSE_CBOR_BSTR) || + (item.dataLen != 0u))) { + ret = WOLFCOSE_E_COSE_BAD_HDR; + } + else if (ret == WOLFCOSE_SUCCESS) { if (recipientValueIsNull != 0) { /* Validate after recipient algorithm classification. */ } @@ -598,6 +604,9 @@ int wc_CoseMac_Verify(const WOLFCOSE_RECIPIENT* recipient, ret = WOLFCOSE_E_CBOR_TYPE; } } + else { + /* No action required */ + } } /* Skip remaining recipients, then reject trailing data (RFC 8949 5.3.1). */ diff --git a/tests/test_cose.c b/tests/test_cose.c index 0a512fe..def7ddf 100644 --- a/tests/test_cose.c +++ b/tests/test_cose.c @@ -12451,10 +12451,12 @@ static void test_cose_encrypt_a128kw_unprotected_alg(void) uint8_t iv[12] = {0}; uint8_t scratch[256]; uint8_t out[512]; + uint8_t malformed[513]; uint8_t plaintext[128]; size_t outLen = 0u; size_t plaintextLen = 0u; size_t count = 0u; + size_t protectedOffset = 0u; const uint8_t* protectedData = NULL; size_t protectedLen = 0u; int64_t label = 0; @@ -12517,6 +12519,7 @@ static void test_cose_encrypt_a128kw_unprotected_alg(void) /* RFC 9053 6.2.1: the AES Key Wrap recipient's protected bucket is empty * and the algorithm is carried in the unprotected header. */ if (ret == 0) { + protectedOffset = ctx.idx; ret = wc_CBOR_DecodeBstr(&ctx, &protectedData, &protectedLen); } if ((ret == 0) && (protectedLen != 0u)) { @@ -12553,6 +12556,28 @@ static void test_cose_encrypt_a128kw_unprotected_alg(void) (XMEMCMP(plaintext, payload, plaintextLen) == 0), "a128kw unprotected payload"); } + TEST_ASSERT((ret != 0) || ((protectedOffset < outLen) && + (outLen < sizeof(malformed)) && + (out[protectedOffset] == 0x40u)), + "a128kw unprotected mutation bounds"); + if ((ret == 0) && (protectedOffset < outLen) && + (outLen < sizeof(malformed)) && + (out[protectedOffset] == 0x40u)) { + (void)XMEMCPY(malformed, out, protectedOffset); + malformed[protectedOffset] = 0x41u; + malformed[protectedOffset + 1u] = 0xA0u; + (void)XMEMCPY(&malformed[protectedOffset + 2u], + &out[protectedOffset + 1u], + outLen - protectedOffset - 1u); + plaintextLen = 0u; + ret = wc_CoseEncrypt_Decrypt(&recipient, 0u, + malformed, outLen + 1u, + NULL, 0u, NULL, 0u, + scratch, sizeof(scratch), &hdr, + plaintext, sizeof(plaintext), &plaintextLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, + "a128kw rejects nonempty protected bucket"); + } wc_CoseKey_Free(&kek); (void)wc_FreeRng(&rng); @@ -13594,7 +13619,7 @@ static void test_cose_mac_rejects_float_recipient_ciphertext(void) ret = wc_CoseMac_Verify(&recipient, 0, msg, msgLen, NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, &payload, &payloadLen); - TEST_ASSERT(ret == WOLFCOSE_E_CBOR_TYPE, + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, "Mac_Verify rejects float recipient ciphertext"); } @@ -13645,7 +13670,7 @@ static void test_cose_mac_rejects_nonempty_recipient_ciphertext(void) ret = wc_CoseMac_Verify(&recipient, 0, msg, outLen + 1u, NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, &payload, &payloadLen); - TEST_ASSERT(ret == WOLFCOSE_E_CBOR_MALFORMED, + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, "Mac_Verify rejects nonempty recipient ciphertext"); (void)memcpy(msg, out, outLen); @@ -13654,8 +13679,8 @@ static void test_cose_mac_rejects_nonempty_recipient_ciphertext(void) ret = wc_CoseMac_Verify(&recipient, 0, msg, outLen, NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, &payload, &payloadLen); - TEST_ASSERT(ret == WOLFCOSE_SUCCESS, - "Mac_Verify accepts null recipient ciphertext"); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, + "Mac_Verify rejects null recipient ciphertext"); wc_CoseKey_Free(&key); } @@ -17758,17 +17783,15 @@ static void test_cose_encrypt_direct_recipient_value(void) ret = wc_CoseEncrypt_Decrypt(&recipient, 0u, msg, outLen, NULL, 0u, NULL, 0u, scratch, sizeof(scratch), &hdr, plaintext, sizeof(plaintext), &plaintextLen); - TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && - (plaintextLen == (sizeof(payload) - 1u)) && - (XMEMCMP(plaintext, payload, plaintextLen) == 0), - "direct value accepts null"); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, + "direct value rejects null"); (void)XMEMCPY(msg, out, outLen); msg[outLen - 1u] = 0x00u; ret = wc_CoseEncrypt_Decrypt(&recipient, 0u, msg, outLen, NULL, 0u, NULL, 0u, scratch, sizeof(scratch), &hdr, plaintext, sizeof(plaintext), &plaintextLen); - TEST_ASSERT(ret == WOLFCOSE_E_CBOR_TYPE, + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, "direct value rejects integer"); (void)XMEMCPY(msg, out, outLen); @@ -17777,7 +17800,7 @@ static void test_cose_encrypt_direct_recipient_value(void) ret = wc_CoseEncrypt_Decrypt(&recipient, 0u, msg, outLen + 1u, NULL, 0u, NULL, 0u, scratch, sizeof(scratch), &hdr, plaintext, sizeof(plaintext), &plaintextLen); - TEST_ASSERT(ret == WOLFCOSE_E_CBOR_MALFORMED, + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, "direct value rejects nonempty bstr"); wc_CoseKey_Free(&key); From 0d1802d93f08391fdef13136458f160479373031 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Fri, 11 Sep 2026 12:08:22 -0700 Subject: [PATCH 7/8] Cover nested recipient traversal --- tests/test_cose.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/test_cose.c b/tests/test_cose.c index def7ddf..f021b08 100644 --- a/tests/test_cose.c +++ b/tests/test_cose.c @@ -17503,6 +17503,18 @@ static void test_cose_encrypt_dup_recipient_unprot_hdr(void) 0x84u, 0x40u, 0xA1u, 0x01u, 0x25u, 0x40u, 0x81u, 0x83u, 0x40u, 0xA1u, 0x01u, 0x25u, 0x40u }; + /* An unselected key-distribution recipient may contain recipients. */ + uint8_t nestedKeyDistSibling[] = { + 0x84u, 0x43u, 0xA1u, 0x01u, 0x01u, + 0xA1u, 0x05u, 0x4Cu, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0x50u, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x82u, + 0x84u, 0x40u, 0xA1u, 0x01u, 0x22u, 0x40u, + 0x81u, 0x83u, 0x40u, 0xA1u, 0x01u, 0x25u, 0x40u, + 0x83u, 0x40u, 0xA1u, 0x01u, 0x25u, 0x40u + }; uint8_t tstrSibling[] = { 0x84u, 0x43u, 0xA1u, 0x01u, 0x01u, 0xA1u, 0x05u, 0x4Cu, @@ -17545,6 +17557,13 @@ static void test_cose_encrypt_dup_recipient_unprot_hdr(void) TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_HDR, "nested skipped Direct recipient rejected (encrypt)"); + ret = wc_CoseEncrypt_Decrypt(&recipient, 1, nestedKeyDistSibling, + sizeof(nestedKeyDistSibling), NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, + plaintext, sizeof(plaintext), &plaintextLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "nested skipped key-distribution recipient traversed"); + ret = wc_CoseEncrypt_Decrypt(&recipient, 1, tstrSibling, sizeof(tstrSibling), NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, From 762f3f1c3653e58599d47ad0baad1aca132c4098 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Mon, 14 Sep 2026 10:59:23 -0700 Subject: [PATCH 8/8] Cover skipped null recipient --- tests/test_cose.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/test_cose.c b/tests/test_cose.c index 36ade14..3310804 100644 --- a/tests/test_cose.c +++ b/tests/test_cose.c @@ -25641,6 +25641,13 @@ static void test_skipped_recipient_tstr_alg(void) 0xA1u, 0x02u, 0x00u, 0x40u }; + /* COSE_recipient [protected {1:-25}, unprotected {}, null]. */ + uint8_t nullValue[] = { + 0x83u, + 0x44u, 0xA1u, 0x01u, 0x38u, 0x18u, + 0xA0u, + 0xF6u + }; TEST_LOG(" [Skipped recipient with tstr alg]\n"); @@ -25660,6 +25667,18 @@ static void test_skipped_recipient_tstr_alg(void) "skipped recipient ignores unrelated header errors"); TEST_ASSERT(alg == WOLFCOSE_ALG_ES256, "skipped recipient still decodes alg"); + + (void)XMEMSET(&ctx, 0, sizeof(ctx)); + ctx.cbuf = nullValue; + ctx.bufSz = sizeof(nullValue); + alg = WOLFCOSE_ALG_UNSET; + ret = wolfCose_DecodeSkippedRecipient(&ctx, &alg); + TEST_ASSERT(ret == WOLFCOSE_SUCCESS, + "skipped recipient accepts null ciphertext"); + TEST_ASSERT(ctx.idx == sizeof(nullValue), + "skipped null recipient consumed"); + TEST_ASSERT(alg == WOLFCOSE_ALG_ECDH_ES_HKDF_256, + "skipped null recipient decodes alg"); } #endif /* WOLFCOSE_ENCRYPT_DECRYPT || WOLFCOSE_MAC_VERIFY */