Skip to content

Commit 3c86784

Browse files
authored
Merge pull request #87 from deeringc/support_fips
Support FIPS-mode in cjose_jwk_derive_ecdh_ephemeral_key
2 parents 46d238b + 0f30d87 commit 3c86784

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

include/cjose/jwk.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ extern "C" {
2626
#endif
2727

2828
/** Enumeration of supported JSON Web Key (JWK) types */
29-
typedef enum {
29+
typedef enum
30+
{
3031
/** RSA Public (or Private) Key */
3132
CJOSE_JWK_KTY_RSA = 1,
3233
/** Elliptic Curve Public (or Private) Key */
@@ -212,7 +213,8 @@ cjose_jwk_t *cjose_jwk_create_RSA_random(size_t keysize, const uint8_t *e, size_
212213
cjose_jwk_t *cjose_jwk_create_RSA_spec(const cjose_jwk_rsa_keyspec *spec, cjose_err *err);
213214

214215
/** Enumeration of supported Elliptic-Curve types */
215-
typedef enum {
216+
typedef enum
217+
{
216218
/** NIST P-256 Prime Curve (secp256r1) */
217219
CJOSE_JWK_EC_P_256 = NID_X9_62_prime256v1,
218220
/** NIST P-384 Prime Curve (secp384r1) */
@@ -357,17 +359,21 @@ cjose_jwk_t *cjose_jwk_import_json(cjose_header_t *json, cjose_err *err);
357359
*
358360
* \param jwk_self [in] The caller's own EC key pair.
359361
* \param jwk_peer [in] The peer's EC public key.
362+
* \param salt [in] An optional salt to apply to the HMAC calculation. Unless FIPS mode is required this can be empty.
363+
* \param salt_len [in] The length of the optional salt.
360364
* \param err [out] An optional error object which can be used to get additional
361365
* information in the event of an error.
362366
* \returns A new JWK representing the ephemeral key, or NULL in the event of
363367
* and error.
364368
*/
365-
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, cjose_err *err);
369+
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(
370+
const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, const uint8_t *salt, size_t salt_len, cjose_err *err);
366371

367372
/**
368373
Deprecated. Alias for cjose_jwk_derive_ecdh_ephemeral_key.
369374
*/
370-
cjose_jwk_t *cjose_jwk_derive_ecdh_secret(const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, cjose_err *err);
375+
cjose_jwk_t *cjose_jwk_derive_ecdh_secret(
376+
const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, const uint8_t *salt, size_t salt_len, cjose_err *err);
371377

372378
#ifdef __cplusplus
373379
}

src/jwk.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,12 +1695,14 @@ static bool _cjose_jwk_evp_key_from_ec_key(const cjose_jwk_t *jwk, EVP_PKEY **ke
16951695
return false;
16961696
}
16971697

1698-
cjose_jwk_t *cjose_jwk_derive_ecdh_secret(const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, cjose_err *err)
1698+
cjose_jwk_t *cjose_jwk_derive_ecdh_secret(
1699+
const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, const uint8_t *salt, size_t salt_len, cjose_err *err)
16991700
{
1700-
return cjose_jwk_derive_ecdh_ephemeral_key(jwk_self, jwk_peer, err);
1701+
return cjose_jwk_derive_ecdh_ephemeral_key(jwk_self, jwk_peer, salt, salt_len, err);
17011702
}
17021703

1703-
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, cjose_err *err)
1704+
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(
1705+
const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, const uint8_t *salt, size_t salt_len, cjose_err *err)
17041706
{
17051707
uint8_t *secret = NULL;
17061708
size_t secret_len = 0;
@@ -1713,11 +1715,10 @@ cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(const cjose_jwk_t *jwk_self, co
17131715
goto _cjose_jwk_derive_shared_secret_fail;
17141716
}
17151717

1716-
// HKDF of the DH shared secret (SHA256, no salt, no info, 256 bit expand)
1718+
// HKDF of the DH shared secret (SHA256, no info, 256 bit expand)
17171719
ephemeral_key_len = 32;
17181720
ephemeral_key = (uint8_t *)cjose_get_alloc()(ephemeral_key_len);
1719-
if (!cjose_jwk_hkdf(EVP_sha256(), (uint8_t *)"", 0, (uint8_t *)"", 0, secret, secret_len, ephemeral_key, ephemeral_key_len,
1720-
err))
1721+
if (!cjose_jwk_hkdf(EVP_sha256(), salt, salt_len, (uint8_t *)"", 0, secret, secret_len, ephemeral_key, ephemeral_key_len, err))
17211722
{
17221723
goto _cjose_jwk_derive_shared_secret_fail;
17231724
}
@@ -1747,11 +1748,8 @@ cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(const cjose_jwk_t *jwk_self, co
17471748
return NULL;
17481749
}
17491750

1750-
bool cjose_jwk_derive_ecdh_bits(const cjose_jwk_t *jwk_self,
1751-
const cjose_jwk_t *jwk_peer,
1752-
uint8_t **output,
1753-
size_t *output_len,
1754-
cjose_err *err)
1751+
bool cjose_jwk_derive_ecdh_bits(
1752+
const cjose_jwk_t *jwk_self, const cjose_jwk_t *jwk_peer, uint8_t **output, size_t *output_len, cjose_err *err)
17551753
{
17561754
EVP_PKEY_CTX *ctx = NULL;
17571755
EVP_PKEY *pkey_self = NULL;
@@ -1865,11 +1863,19 @@ bool cjose_jwk_hkdf(const EVP_MD *md,
18651863
// HKDF-Extract, HMAC-SHA256(salt, IKM) -> PRK
18661864
unsigned int prk_len;
18671865
unsigned char prk[EVP_MAX_MD_SIZE];
1868-
HMAC(md, salt, salt_len, ikm, ikm_len, prk, &prk_len);
1866+
if (NULL == HMAC(md, salt, salt_len, ikm, ikm_len, prk, &prk_len))
1867+
{
1868+
CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1869+
return false;
1870+
}
18691871

18701872
// HKDF-Expand, HMAC-SHA256(PRK,0x01) -> OKM
18711873
const unsigned char t[] = { 0x01 };
1872-
HMAC(md, prk, prk_len, t, sizeof(t), okm, NULL);
1874+
if (NULL == HMAC(md, prk, prk_len, t, sizeof(t), okm, NULL))
1875+
{
1876+
CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
1877+
return false;
1878+
}
18731879

18741880
return true;
18751881
}

0 commit comments

Comments
 (0)