Skip to content
Open
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
38 changes: 19 additions & 19 deletions doc/dox_comments/header_files/tsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.
Expand All @@ -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
*/
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
21 changes: 16 additions & 5 deletions tests/api/test_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,12 @@ int test_wc_OidGetHash(void)
#endif
#ifdef WOLFSSL_SHA512
SHA512h,
#ifndef WOLFSSL_NOSHA512_224
SHA512_224h,
Comment thread
yosuke-wolfssl marked this conversation as resolved.
#endif
#ifndef WOLFSSL_NOSHA512_256
SHA512_256h,
#endif
#endif
#ifdef WOLFSSL_SHA3
SHA3_224h,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]);
}
Expand Down
71 changes: 65 additions & 6 deletions tests/api/test_tsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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();
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
38 changes: 26 additions & 12 deletions wolfcrypt/src/asn_tsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -124,17 +123,25 @@ 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");

/* Validate parameters. */
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) &&
Comment thread
yosuke-wolfssl marked this conversation as resolved.
(req->imprint.hashSz != (word32)digestSz))) {
ret = BAD_FUNC_ARG;
}
}
/* Policy, when set, must fit. */
if ((ret == 0) && (req->policySz > sizeof(req->policy))) {
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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)
Expand Down
14 changes: 14 additions & 0 deletions wolfcrypt/src/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment thread
yosuke-wolfssl marked this conversation as resolved.
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;
Expand Down
Loading
Loading