diff --git a/doc/dox_comments/header_files/tsp.h b/doc/dox_comments/header_files/tsp.h index e5d17d4812..9e61d6f43f 100644 --- a/doc/dox_comments/header_files/tsp.h +++ b/doc/dox_comments/header_files/tsp.h @@ -18,9 +18,8 @@ // hash the data to be time-stamped into hash wc_TspRequest_Init(&req); - req.imprint.hashAlgOID = SHA256h; - XMEMCPY(req.imprint.hash, hash, sizeof(hash)); - req.imprint.hashSz = (word32)sizeof(hash); + wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256); + wc_TspRequest_SetHash(&req, hash, (word32)sizeof(hash)); req.certReq = 1; \endcode @@ -33,9 +32,8 @@ int wc_TspRequest_Init(TspRequest* req); /*! \ingroup TSP - \brief This function sets the message imprint hash algorithm and hash size - of a TimeStampReq from a hash type. After calling, fill - req->imprint.hash with the digest of the data to be time-stamped. + \brief This function sets the message imprint hash algorithm of a + TimeStampReq from a hash type. Any digest already set is discarded. \return 0 Returned on successfully setting the hash algorithm. \return BAD_FUNC_ARG Returned when req is NULL. @@ -54,11 +52,12 @@ int wc_TspRequest_Init(TspRequest* req); wc_TspRequest_Init(&req); wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256); - XMEMCPY(req.imprint.hash, hash, sizeof(hash)); + wc_TspRequest_SetHash(&req, hash, (word32)sizeof(hash)); req.certReq = 1; \endcode \sa wc_TspRequest_Init + \sa wc_TspRequest_SetHash \sa wc_TspRequest_GetHashType \sa wc_TspRequest_Encode */ @@ -133,11 +132,15 @@ int wc_TspRequest_GetHash(const TspRequest* req, byte* hash, word32* hashSz); \brief This function sets the message imprint hash of a TimeStampReq. The hash and its length are copied into the message imprint. Set the hash - algorithm separately with wc_TspRequest_SetHashType(). + algorithm first with wc_TspRequest_SetHashType() - hashSz must be the + digest size of that algorithm. \return 0 Returned on successfully setting the hash. \return BAD_FUNC_ARG Returned when req or hash is NULL or hashSz is 0. - \return BUFFER_E Returned when hashSz is too big for the message imprint. + \return HASH_TYPE_E Returned when the hash algorithm is not set or not + available. + \return BUFFER_E Returned when hashSz is not the algorithm's digest size + or is too big for the message imprint. \param [in,out] req Pointer to the TspRequest structure to update. \param [in] hash Hash of the data to be time-stamped. @@ -151,7 +154,7 @@ int wc_TspRequest_GetHash(const TspRequest* req, byte* hash, word32* hashSz); wc_TspRequest_Init(&req); wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256); - wc_TspRequest_SetHash(&req, hash, sizeof(hash)); + wc_TspRequest_SetHash(&req, hash, (word32)sizeof(hash)); \endcode \sa wc_TspRequest_GetHash @@ -374,9 +377,8 @@ void wc_TspRequest_SetCertReq(TspRequest* req, int val); have a leading zero byte. \return 0 Returned on successfully encoding the request. - \return BAD_FUNC_ARG Returned when req or outSz is NULL, the message - imprint hash is not set, a field is too long for its array or the nonce - has a leading zero byte. + \return BAD_FUNC_ARG Returned when req or outSz is NULL, or a field is + unset, the wrong length or not encodable as given. \return BUFFER_E Returned when out is not NULL and the encoding is longer than outSz. \return ASN_UNKNOWN_OID_E Returned when the hash algorithm is not @@ -636,7 +638,8 @@ int wc_TspTstInfo_GetMsgImprint(const TspTstInfo* tstInfo, word32* hashOID, \return 0 Returned on successfully setting the message imprint. \return BAD_FUNC_ARG Returned when tstInfo or hash is NULL or hashSz is 0. - \return BUFFER_E Returned when hashSz is too big for the message imprint. + \return BUFFER_E Returned when hashSz is too big for the message imprint + or not the digest size of hashOID. \param [in,out] tstInfo Pointer to the TspTstInfo structure to update. \param [in] hashOID Hash algorithm OID sum: SHA256h, etc. @@ -897,11 +900,8 @@ int wc_TspTstInfo_SetFromRequest(TspTstInfo* tstInfo, const TspRequest* req, wc_TspTstInfo_SignWithPkcs7() which encodes and signs in one call. \return 0 Returned on successfully encoding the TSTInfo. - \return BAD_FUNC_ARG Returned when tstInfo or outSz is NULL, a required - field is not set or empty, the hash is too long, the genTime is not a - valid GeneralizedTime, the tsa is empty, the serial number or nonce is - empty or has a leading zero byte or accuracy millis or micros is out of - range. + \return BAD_FUNC_ARG Returned when tstInfo or outSz is NULL, or a field + is unset, the wrong length or not encodable as given. \return BUFFER_E Returned when out is not NULL and the encoding is longer than outSz. \return ASN_UNKNOWN_OID_E Returned when the hash algorithm is not diff --git a/tests/api/test_hash.c b/tests/api/test_hash.c index 4ceea2c81a..d4b5b6dffe 100644 --- a/tests/api/test_hash.c +++ b/tests/api/test_hash.c @@ -780,6 +780,12 @@ int test_wc_OidGetHash(void) #endif #ifdef WOLFSSL_SHA512 SHA512h, + #ifndef WOLFSSL_NOSHA512_224 + SHA512_224h, + #endif + #ifndef WOLFSSL_NOSHA512_256 + SHA512_256h, + #endif #endif #ifdef WOLFSSL_SHA3 SHA3_224h, @@ -813,6 +819,15 @@ int test_wc_OidGetHash(void) #endif #ifndef WOLFSSL_SHA512 SHA512h, + SHA512_224h, + SHA512_256h, + #else + #ifdef WOLFSSL_NOSHA512_224 + SHA512_224h, + #endif + #ifdef WOLFSSL_NOSHA512_256 + SHA512_256h, + #endif #endif #ifndef WOLFSSL_SHA3 SHA3_224h, @@ -1088,11 +1103,7 @@ int test_wc_HashFeatureCoverage(void) { int oid = wc_HashGetOID(supportedHash[i]); ExpectIntGT(oid, 0); - /* wc_OidGetHash() has no case for SHA512_224h/SHA512_256h (no - * OID assigned upstream for those two truncated variants), so - * the round trip only holds for the other digests. */ - if (oid > 0 && supportedHash[i] != WC_HASH_TYPE_SHA512_224 && - supportedHash[i] != WC_HASH_TYPE_SHA512_256) { + if (oid > 0) { enum wc_HashType rtType = wc_OidGetHash(oid); ExpectIntEQ((int)rtType, (int)supportedHash[i]); } diff --git a/tests/api/test_tsp.c b/tests/api/test_tsp.c index 1a2eb613a7..55c29abd66 100644 --- a/tests/api/test_tsp.c +++ b/tests/api/test_tsp.c @@ -117,7 +117,9 @@ int test_wc_TspRequest_SetHashType(void) #if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \ defined(WOLFSSL_TSP_REQUESTER) TspRequest req; + byte zeros[WC_SHA256_DIGEST_SIZE]; + XMEMSET(zeros, 0, sizeof(zeros)); ExpectIntEQ(wc_TspRequest_Init(&req), 0); /* Bad argument. */ @@ -127,17 +129,25 @@ int test_wc_TspRequest_SetHashType(void) ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_NONE), WC_NO_ERR_TRACE(HASH_TYPE_E)); - /* SHA-256 sets the algorithm OID and the digest size. */ + /* SHA-256 sets the algorithm OID - the digest is set separately. */ ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0); ExpectIntEQ(req.imprint.hashAlgOID, SHA256h); - ExpectIntEQ(req.imprint.hashSz, WC_SHA256_DIGEST_SIZE); + ExpectIntEQ(req.imprint.hashSz, 0); #ifdef WOLFSSL_SHA384 - /* A different algorithm sets a different OID and size. */ + /* A different algorithm sets a different OID. */ ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA384), 0); ExpectIntEQ(req.imprint.hashAlgOID, SHA384h); - ExpectIntEQ(req.imprint.hashSz, WC_SHA384_DIGEST_SIZE); + ExpectIntEQ(req.imprint.hashSz, 0); #endif + + /* Setting the algorithm discards a digest already set. */ + ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0); + ExpectIntEQ(wc_TspRequest_SetHash(&req, tsHashedMsg, + (word32)sizeof(tsHashedMsg)), 0); + ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0); + ExpectIntEQ(req.imprint.hashSz, 0); + ExpectBufEQ(req.imprint.hash, zeros, (int)sizeof(zeros)); #endif return EXPECT_RESULT(); } @@ -200,6 +210,14 @@ int test_wc_TspRequest_GetSetHash(void) /* Hash too big for the message imprint. */ ExpectIntEQ(wc_TspRequest_SetHash(&req, hash, WC_TSP_MAX_HASH_SZ + 1), WC_NO_ERR_TRACE(BUFFER_E)); + /* Hash algorithm not set yet. */ + ExpectIntEQ(wc_TspRequest_SetHash(&req, hash, (word32)sizeof(hash)), + WC_NO_ERR_TRACE(HASH_TYPE_E)); + + ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0); + /* One byte short of the algorithm's digest size. */ + ExpectIntEQ(wc_TspRequest_SetHash(&req, hash, (word32)sizeof(hash) - 1), + WC_NO_ERR_TRACE(BUFFER_E)); /* Set the hash and length. */ ExpectIntEQ(wc_TspRequest_SetHash(&req, hash, (word32)sizeof(hash)), 0); @@ -434,7 +452,22 @@ int test_wc_TspRequest_Encode(void) req.imprint.hashSz = WC_TSP_MAX_HASH_SZ + 1; ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); - req.imprint.hashSz = (word32)sizeof(tsHashedMsg); + /* Hash length that is not the algorithm's digest size. */ + req.imprint.hashSz = (word32)sizeof(tsHashedMsg) - 1; + ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + /* Algorithm set but the digest never supplied - not encoded. */ + ExpectIntEQ(wc_TspRequest_Init(&req), 0); + ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0); + ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + /* Setting the algorithm after the digest discards the digest. */ + ExpectIntEQ(wc_TspRequest_SetHash(&req, tsHashedMsg, + (word32)sizeof(tsHashedMsg)), 0); + ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0); + ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + test_tsp_set_hash(&req.imprint); /* Policy too long. */ req.policySz = MAX_OID_SZ + 1; ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz), @@ -483,6 +516,19 @@ int test_wc_TspRequest_Encode(void) sz = (word32)sizeof(enc); ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &sz), 0); ExpectIntGT(sz, (word32)sizeof(tsMinReqDer)); + +#if (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) && \ + !defined(HAVE_SELFTEST) && defined(WOLFSSL_SHA512) && \ + !defined(WOLFSSL_NOSHA512_224) + /* SHA-512/224 imprint - the OID maps back to the algorithm. */ + ExpectIntEQ(wc_TspRequest_Init(&req), 0); + ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA512_224), 0); + ExpectIntEQ(req.imprint.hashAlgOID, SHA512_224h); + ExpectIntEQ(wc_TspRequest_SetHash(&req, tsHashedMsg, + WC_SHA512_224_DIGEST_SIZE), 0); + sz = (word32)sizeof(enc); + ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &sz), 0); +#endif #endif return EXPECT_RESULT(); } @@ -867,7 +913,8 @@ int test_wc_TspTstInfo_Setters(void) static const byte policy[] = { 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x67, 0x01 }; - static const byte hash[] = { 0xde, 0xad, 0xbe, 0xef }; + /* SHA-256 sized hash - the length must match the algorithm. */ + static const byte hash[32] = { 0xde, 0xad, 0xbe, 0xef }; static const byte genTime[] = "20260610120000Z"; static const byte nonce[] = { 0x12, 0x34 }; /* Name of TSA: dNSName GeneralName. */ @@ -906,6 +953,14 @@ int test_wc_TspTstInfo_Setters(void) WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, SHA256h, bigHash, (word32)sizeof(bigHash)), WC_NO_ERR_TRACE(BUFFER_E)); +#ifndef NO_SHA256 + /* One byte short of the digest size of the algorithm. */ + ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, SHA256h, hash, + (word32)sizeof(hash) - 1), WC_NO_ERR_TRACE(BUFFER_E)); +#endif + /* An unknown algorithm has no digest size - any length accepted. */ + ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, 1, hash, + (word32)sizeof(hash) - 1), 0); ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, SHA256h, hash, (word32)sizeof(hash)), 0); ExpectIntEQ(wc_TspTstInfo_GetMsgImprint(&tst, &hashOID, &out, &outSz), 0); @@ -1033,6 +1088,10 @@ int test_wc_TspTstInfo_Encode(void) WC_NO_ERR_TRACE(BAD_FUNC_ARG)); /* Hash too long. */ tst.imprint.hashSz = WC_TSP_MAX_HASH_SZ + 1; + ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + /* Hash length that is not the algorithm's digest size. */ + tst.imprint.hashSz = (word32)sizeof(tsHashedMsg) - 1; ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); tst.imprint.hashSz = (word32)sizeof(tsHashedMsg); diff --git a/wolfcrypt/src/asn_tsp.c b/wolfcrypt/src/asn_tsp.c index dbe491253d..edb93324cf 100644 --- a/wolfcrypt/src/asn_tsp.c +++ b/wolfcrypt/src/asn_tsp.c @@ -112,9 +112,8 @@ enum { * @param [in, out] outSz On in, length of buffer in bytes. * On out, length of encoding in bytes. * @return 0 on success. - * @return BAD_FUNC_ARG when req or outSz is NULL, the message imprint hash - * is not set, a field is too long for its array or the nonce has a - * leading zero byte. + * @return BAD_FUNC_ARG when req or outSz is NULL, or a field is unset, the + * wrong length or not encodable as given. * @return BUFFER_E when out is not NULL and encoding is longer than outSz. * @return ASN_UNKNOWN_OID_E when the hash algorithm is not recognized. * @return MEMORY_E on dynamic memory allocation failure. @@ -124,6 +123,7 @@ int wc_TspRequest_Encode(const TspRequest* req, byte* out, word32* outSz) DECL_ASNSETDATA(dataASN, tspReqASN_Length); int ret = 0; word32 sz = 0; + int digestSz = 0; WOLFSSL_ENTER("wc_TspRequest_Encode"); @@ -131,10 +131,17 @@ int wc_TspRequest_Encode(const TspRequest* req, byte* out, word32* outSz) if ((req == NULL) || (outSz == NULL)) { ret = BAD_FUNC_ARG; } - /* The message imprint is the only required field. */ - if ((ret == 0) && ((req->imprint.hashSz == 0) || - (req->imprint.hashSz > sizeof(req->imprint.hash)))) { - ret = BAD_FUNC_ARG; + /* The message imprint is the only required field. Its length is checked + * against the hash algorithm when the algorithm is known and available. */ + if (ret == 0) { + digestSz = wc_HashGetDigestSize( + wc_OidGetHash((int)req->imprint.hashAlgOID)); + if ((req->imprint.hashSz == 0) || + (req->imprint.hashSz > sizeof(req->imprint.hash)) || + ((digestSz > 0) && + (req->imprint.hashSz != (word32)digestSz))) { + ret = BAD_FUNC_ARG; + } } /* Policy, when set, must fit. */ if ((ret == 0) && (req->policySz > sizeof(req->policy))) { @@ -447,11 +454,8 @@ enum { * @param [in, out] outSz On in, length of buffer in bytes. * On out, length of encoding in bytes. * @return 0 on success. - * @return BAD_FUNC_ARG when tstInfo or outSz is NULL, a required field of - * tstInfo is not set or empty, the hash is too long, the genTime - * is not a valid GeneralizedTime, the tsa is empty, the serial - * number or nonce is empty or has a leading zero byte or accuracy - * millis or micros is out of range. + * @return BAD_FUNC_ARG when tstInfo or outSz is NULL, or a field is unset, + * the wrong length or not encodable as given. * @return BUFFER_E when out is not NULL and encoding is longer than outSz. * @return ASN_UNKNOWN_OID_E when the hash algorithm is not recognized. * @return ASN_TIME_E when getting the current time failed. @@ -462,6 +466,7 @@ int wc_TspTstInfo_Encode(const TspTstInfo* tstInfo, byte* out, word32* outSz) DECL_ASNSETDATA(dataASN, tspTstInfoASN_Length); int ret = 0; word32 sz = 0; + int digestSz = 0; #if !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES) byte timeBuf[ASN_GENERALIZED_TIME_SIZE]; #endif @@ -480,6 +485,15 @@ int wc_TspTstInfo_Encode(const TspTstInfo* tstInfo, byte* out, word32* outSz) (tstInfo->serial == NULL))) { ret = BAD_FUNC_ARG; } + /* The imprint length must match the hash algorithm when the algorithm is + * known and available. */ + if (ret == 0) { + digestSz = wc_HashGetDigestSize( + wc_OidGetHash((int)tstInfo->imprint.hashAlgOID)); + if ((digestSz > 0) && (tstInfo->imprint.hashSz != (word32)digestSz)) { + ret = BAD_FUNC_ARG; + } + } /* genTime, when set, must be a valid GeneralizedTime of RFC 3161. */ if ((ret == 0) && (tstInfo->genTime != NULL) && (TspCheckGenTimeSyntax(tstInfo->genTime, tstInfo->genTimeSz) diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index f421f7188e..927c79d57d 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -325,6 +325,20 @@ enum wc_HashType wc_OidGetHash(int oid) hash_type = WC_ERR_TRACE(WC_HASH_TYPE_NONE); #endif break; + case SHA512_224h: + #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) + hash_type = WC_HASH_TYPE_SHA512_224; + #else + hash_type = WC_ERR_TRACE(WC_HASH_TYPE_NONE); + #endif + break; + case SHA512_256h: + #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) + hash_type = WC_HASH_TYPE_SHA512_256; + #else + hash_type = WC_ERR_TRACE(WC_HASH_TYPE_NONE); + #endif + break; case SHA3_224h: #ifdef WOLFSSL_SHA3 hash_type = WC_HASH_TYPE_SHA3_224; diff --git a/wolfcrypt/src/tsp.c b/wolfcrypt/src/tsp.c index 33b8211839..8a1859180c 100644 --- a/wolfcrypt/src/tsp.c +++ b/wolfcrypt/src/tsp.c @@ -103,8 +103,7 @@ int wc_TspRequest_GetHashType(const TspRequest* req, enum wc_HashType* hashType) #ifdef WOLFSSL_TSP_REQUESTER /* Set the message imprint hash algorithm of a TimeStampReq. * - * Sets the hash algorithm OID and hash size from the hash type. The caller - * fills req->imprint.hash with the digest of the data to be time-stamped. + * Sets the hash algorithm OID and discards any digest already set. * * @param [in, out] req TimeStampReq object. * @param [in] hashType Hash algorithm to use - e.g. WC_HASH_TYPE_SHA256. @@ -143,7 +142,9 @@ int wc_TspRequest_SetHashType(TspRequest* req, enum wc_HashType hashType) } if (ret == 0) { req->imprint.hashAlgOID = (word32)oid; - req->imprint.hashSz = (word32)digestSz; + /* A digest of the previous algorithm is no longer valid. */ + XMEMSET(req->imprint.hash, 0, sizeof(req->imprint.hash)); + req->imprint.hashSz = 0; } return ret; @@ -188,18 +189,22 @@ int wc_TspRequest_GetHash(const TspRequest* req, byte* hash, word32* hashSz) /* Set the message imprint hash of a TimeStampReq. * * Copies the hash and its length into the message imprint. The hash algorithm - * is set separately - see wc_TspRequest_SetHashType(). + * must be set first with wc_TspRequest_SetHashType() and hashSz must be its + * digest size. * * @param [in, out] req TimeStampReq object. * @param [in] hash Hash of the data to be time-stamped. * @param [in] hashSz Length of hash in bytes. * @return 0 on success. * @return BAD_FUNC_ARG when req or hash is NULL or hashSz is 0. - * @return BUFFER_E when hashSz is too big for the message imprint. + * @return HASH_TYPE_E when the hash algorithm is not set or not available. + * @return BUFFER_E when hashSz is not the algorithm's digest size or is too + * big for the message imprint. */ int wc_TspRequest_SetHash(TspRequest* req, const byte* hash, word32 hashSz) { int ret = 0; + int digestSz = 0; /* Validate parameters. */ if ((req == NULL) || (hash == NULL) || (hashSz == 0)) { @@ -209,6 +214,17 @@ int wc_TspRequest_SetHash(TspRequest* req, const byte* hash, word32 hashSz) ret = BUFFER_E; } + if (ret == 0) { + /* The digest must be the length of the algorithm already set. */ + digestSz = wc_HashGetDigestSize( + wc_OidGetHash((int)req->imprint.hashAlgOID)); + if (digestSz <= 0) { + ret = HASH_TYPE_E; + } + else if (hashSz != (word32)digestSz) { + ret = BUFFER_E; + } + } if (ret == 0) { XMEMCPY(req->imprint.hash, hash, hashSz); req->imprint.hashSz = hashSz; @@ -594,11 +610,14 @@ int wc_TspTstInfo_GetMsgImprint(const TspTstInfo* tstInfo, word32* hashOID, * @param [in] hashSz Length of hash in bytes. * @return 0 on success. * @return BAD_FUNC_ARG when tstInfo or hash is NULL or hashSz is 0. - * @return BUFFER_E when hashSz is too big for the message imprint. + * @return BUFFER_E when hashSz is too big for the message imprint or not + * the digest size of hashOID. */ int wc_TspTstInfo_SetMsgImprint(TspTstInfo* tstInfo, word32 hashOID, const byte* hash, word32 hashSz) { + int digestSz; + /* Validate parameters. */ if ((tstInfo == NULL) || (hash == NULL) || (hashSz == 0)) { return BAD_FUNC_ARG; @@ -606,6 +625,12 @@ int wc_TspTstInfo_SetMsgImprint(TspTstInfo* tstInfo, word32 hashOID, if (hashSz > sizeof(tstInfo->imprint.hash)) { return BUFFER_E; } + /* The digest size of an unknown or unavailable algorithm is not known - + * the length is only checked against a known one. */ + digestSz = wc_HashGetDigestSize(wc_OidGetHash((int)hashOID)); + if ((digestSz > 0) && (hashSz != (word32)digestSz)) { + return BUFFER_E; + } tstInfo->imprint.hashAlgOID = hashOID; XMEMCPY(tstInfo->imprint.hash, hash, hashSz);