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
6 changes: 5 additions & 1 deletion kernel-src/noise.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,10 @@ static int __must_check message_encrypt(u8 *dst_ciphertext, size_t dst_ciphertex
size_t src_len, u8 key[NOISE_SYMMETRIC_KEY_LEN],
u8 hash[NOISE_HASH_LEN])
{
/* For Noise_IK, an all-zeros IV is used, and the key itself guarantees
* uniqueness of the { key, iv } tuple, via wc_ecc_make_keypair_exim(),
* mix_dh(), mix_precomputed_dh(), and mix_psk().
*/
int ret = wc_AesGcm_oneshot_encrypt(dst_ciphertext, dst_ciphertext_space, key, NOISE_SYMMETRIC_KEY_LEN, src_plaintext, src_len,
NULL /* iv */, 0,
hash, NOISE_HASH_LEN, NOISE_AUTHTAG_LEN);
Expand Down Expand Up @@ -721,7 +725,7 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
goto out;
}

/* Get an exclusive lock here, even though initially we only need a read
/* Get an exclusive lock here, even though initially we only need a read
* lock -- this avoids a race window after the defensive tests and
* before storing the new ephemeral key. The attack tests have a
* negligible CPU footprint, so the atomic ops (identically expensive
Expand Down
4 changes: 3 additions & 1 deletion kernel-src/receive.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,10 @@ static int wg_receive_handshake_packet(struct wg_device *wg,
wg_packet_send_keepalive(peer);
ret = 0;
}
else
else {
WC_DEBUG_PR_CODEPOINT();
ret = -ECANCELED;
}
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions kernel-src/selftest/allowedips.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ static __init bool randomized_test(void)
mutate_mask[k] = 0xff;
mutate_mask[k] = 0xff
<< ((8 - (mutate_amount % 8)) % 8);
for (k = mutate_amount/8 + 1; k < 4; ++k)
for (k = mutate_amount / 8 + 1; k < 4; ++k)
mutate_mask[k] = 0;
for (k = 0; k < 4; ++k)
mutated[k] = (mutated[k] & mutate_mask[k]) |
Expand Down Expand Up @@ -369,7 +369,7 @@ static __init bool randomized_test(void)
mutate_mask[k] = 0xff
<< ((8 - (mutate_amount % 8)) % 8);
/* 16 bytes of IPv6 address */
for (k = mutate_amount/8 + 1; k < 16; ++k)
for (k = mutate_amount / 8 + 1; k < 16; ++k)
mutate_mask[k] = 0;
for (k = 0; k < 16; ++k)
mutated[k] = (mutated[k] & mutate_mask[k]) |
Expand Down
15 changes: 13 additions & 2 deletions kernel-src/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,19 @@ static int __must_check wg_packet_send_handshake_initiation(struct wg_peer *peer
wg_timers_any_authenticated_packet_traversal(peer);
wg_timers_any_authenticated_packet_sent(peer);
}
else
WC_DEBUG_PR_CODEPOINT_VAL(ret);
}
else
WC_DEBUG_PR_CODEPOINT_VAL(ret);
wg_timers_handshake_initiated(peer); /* restart retry timer even
* if send failed.
*/
}
else
else {
WC_DEBUG_PR_CODEPOINT();
ret = -ECANCELED;
}

if (ret != 0)
(void)atomic64_cmpxchg_relaxed(&peer->last_sent_handshake,
Expand Down Expand Up @@ -132,7 +138,10 @@ int __must_check wg_packet_send_handshake_response(struct wg_peer *peer)
if (ret == 0) {
if (! wg_noise_handshake_begin_session(&peer->handshake,
&peer->keypairs))
{
WC_DEBUG_PR_CODEPOINT();
ret = -ECANCELED;
}
}
if (ret == 0) {
wg_timers_session_derived(peer);
Expand All @@ -145,8 +154,10 @@ int __must_check wg_packet_send_handshake_response(struct wg_peer *peer)
HANDSHAKE_DSCP);
}
}
else
else {
WC_DEBUG_PR_CODEPOINT();
ret = -ECANCELED;
}

memzero_explicit(&packet, sizeof packet);

Expand Down
98 changes: 94 additions & 4 deletions kernel-src/wolfcrypt_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int wc_hmac_oneshot(const int type, byte *out, const size_t out_space, const byt

static const byte ZeroNonce[AES_IV_SIZE] = {};

int wc_AesGcm_Appended_Tag_Encrypt(Aes* aes, byte* out, word32 out_space,
static int wc_AesGcm_Appended_Tag_Encrypt(Aes* aes, byte* out, word32 out_space,
const byte* in, word32 in_sz,
const byte* iv, word32 iv_sz,
const byte* authIn, word32 authIn_sz,
Expand All @@ -88,12 +88,40 @@ int wc_AesGcm_Appended_Tag_Encrypt(Aes* aes, byte* out, word32 out_space,
iv_sz = sizeof(ZeroNonce);
}

#ifdef WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED
WC_DEBUG_PR_NEG_RET(wc_AesGcmEncrypt(aes, out, in, in_sz, iv, iv_sz,
out + in_sz, authTag_len,
authIn, authIn_sz));
out + in_sz, authTag_len,
authIn, authIn_sz));
#else /* !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED */
/* avoid wc_AesGcmEncrypt(), to stay in-boundary for FIPS. */
#ifdef WOLFSSL_AESGCM_STREAM
{
int ret = wc_AesGcmInit(aes, NULL /* key */, 0 /* len */, iv, iv_sz);
if (ret < 0)
WC_DEBUG_PR_NEG_RET(ret);
ret = wc_AesGcmEncryptUpdate(aes, out, in, in_sz, authIn, authIn_sz);
if (ret < 0)
WC_DEBUG_PR_NEG_RET(ret);
WC_DEBUG_PR_NEG_RET(wc_AesGcmEncryptFinal(aes, out + in_sz, authTag_len));
}
#else
{
byte ivOut[GCM_NONCE_MAX_SZ];
int ret;
if (iv_sz > GCM_NONCE_MAX_SZ)
WC_DEBUG_PR_NEG_RET(BAD_LENGTH_E);
ret = wc_AesGcmSetExtIV(aes, iv, iv_sz);
if (ret < 0)
WC_DEBUG_PR_NEG_RET(ret);
WC_DEBUG_PR_NEG_RET(wc_AesGcmEncrypt_ex(aes, out, in, in_sz, ivOut, iv_sz,
out + in_sz, authTag_len,
authIn, authIn_sz));
}
#endif
#endif /* !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED */
}

int wc_AesGcm_Appended_Tag_Decrypt(Aes* aes, byte* out, word32 out_space,
static int wc_AesGcm_Appended_Tag_Decrypt(Aes* aes, byte* out, word32 out_space,
const byte* in, word32 in_sz,
const byte* iv, word32 iv_sz,
const byte* authIn, word32 authIn_sz,
Expand Down Expand Up @@ -176,6 +204,17 @@ int wc_AesGcm_oneshot_decrypt(byte* out, size_t out_space, const byte* key, size

#ifdef WOLFSSL_AESGCM_STREAM

/* Don't incur the FIPS check overhead inside the loop -- the Final() call
* below will check and error if the module entered degraded state during
* the loop.
*/
#if defined(HAVE_FIPS) && !defined(FIPS_NO_WRAPPERS)
#undef wc_AesGcmDecryptUpdate
#undef wc_AesGcmEncryptUpdate
typeof(wc_AesGcmDecryptUpdate_fips) wc_AesGcmDecryptUpdate;
typeof(wc_AesGcmEncryptUpdate_fips) wc_AesGcmEncryptUpdate;
#endif

static __always_inline bool wc_AesGcm_crypt_sg_inplace(struct scatterlist *src, const size_t src_len,
const u8 *ad, const size_t ad_len,
u64 nonce,
Expand Down Expand Up @@ -319,6 +358,11 @@ static __always_inline bool wc_AesGcm_crypt_sg_inplace(struct scatterlist *src,
return ret == 0;
}

#if defined(HAVE_FIPS) && !defined(FIPS_NO_WRAPPERS)
#define wc_AesGcmDecryptUpdate wc_AesGcmDecryptUpdate_fips
#define wc_AesGcmEncryptUpdate wc_AesGcmEncryptUpdate_fips
#endif

#else /* !WOLFSSL_AESGCM_STREAM */

static __always_inline bool wc_AesGcm_crypt_sg_inplace(struct scatterlist *src, const size_t src_len,
Expand Down Expand Up @@ -400,13 +444,36 @@ static __always_inline bool wc_AesGcm_crypt_sg_inplace(struct scatterlist *src,
full_nonce, (word32)sizeof(full_nonce),
miter.addr + length, WC_AES_BLOCK_SIZE,
ad, (word32)ad_len);
if (ret < 0)
WC_DEBUG_PR_CODEPOINT_VAL(ret);
}
else {
#ifdef WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED
ret = wc_AesGcmEncrypt(aes, miter.addr,
miter.addr, (word32)length,
full_nonce, (word32)sizeof(full_nonce),
miter.addr + length, WC_AES_BLOCK_SIZE,
ad, (word32)ad_len);
if (ret < 0)
WC_DEBUG_PR_CODEPOINT_VAL(ret);
#else /* !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED */
/* Use wc_AesGcmSetExtIV() and wc_AesGcmEncrypt_ex(), not
* wc_AesGcmEncrypt(), to stay in-boundary for FIPS.
*/
byte ivOut[GCM_NONCE_MAX_SZ];
ret = wc_AesGcmSetExtIV(aes, full_nonce, (word32)sizeof(full_nonce));
if (ret == 0) {
ret = wc_AesGcmEncrypt_ex(aes, miter.addr,
miter.addr, (word32)length,
ivOut, (word32)sizeof(full_nonce),
miter.addr + length, WC_AES_BLOCK_SIZE,
ad, (word32)ad_len);
if (ret < 0)
WC_DEBUG_PR_CODEPOINT_VAL(ret);
}
else
WC_DEBUG_PR_CODEPOINT_VAL(ret);
#endif /* !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED */
}

sg_miter_stop(&miter);
Expand Down Expand Up @@ -437,11 +504,32 @@ static __always_inline bool wc_AesGcm_crypt_sg_inplace(struct scatterlist *src,
}
else {
scatterwalk_map_and_copy(buf, src, 0, src_len, 0);
#ifdef WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED
ret = wc_AesGcmEncrypt(aes, buf,
buf, (word32)src_len,
full_nonce, (word32)sizeof(full_nonce),
buf + src_len, WC_AES_BLOCK_SIZE,
ad, (word32)ad_len);
if (ret < 0)
WC_DEBUG_PR_CODEPOINT_VAL(ret);
#else /* !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED */
{
/* Avoid wc_AesGcmEncrypt() to stay in-boundary for FIPS. */
byte ivOut[GCM_NONCE_MAX_SZ];
ret = wc_AesGcmSetExtIV(aes, full_nonce, (word32)sizeof(full_nonce));
if (ret == 0) {
ret = wc_AesGcmEncrypt_ex(aes, buf,
buf, (word32)src_len,
ivOut, (word32)sizeof(full_nonce),
buf + src_len, WC_AES_BLOCK_SIZE,
ad, (word32)ad_len);
if (ret < 0)
WC_DEBUG_PR_CODEPOINT_VAL(ret);
}
else
WC_DEBUG_PR_CODEPOINT_VAL(ret);
}
#endif /* !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED */
if (ret == 0)
scatterwalk_map_and_copy(buf, src, 0, src_len + WC_AES_BLOCK_SIZE, 1);
else
Expand Down Expand Up @@ -889,6 +977,8 @@ int wc_linuxkm_drbg_init_ctx(struct wc_rng_bank **ctx) {
WC_DUMP_BACKTRACE_NONDEBUG;
}
}
else
WC_DEBUG_PR_CODEPOINT_VAL(ret);

return (ret == 0) ? ret : -ECANCELED;
}
Expand Down
17 changes: 4 additions & 13 deletions kernel-src/wolfcrypt_glue.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
#define WOLFCRYPTO_SHIM_H

#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/types.h>

#if !defined(HAVE_AESGCM) || (!defined(HAVE_AESGCM_DECRYPT) && defined(NO_AES_DECRYPT))
#error libwolfssl missing AES-GCM with streaming
#error libwolfssl missing AES-GCM
#endif
#if defined(NO_SHA256)
#error libwolfssl missing SHA256
Expand Down Expand Up @@ -69,6 +70,7 @@
#define WC_DEBUG_PR_NULL_RET(x) do { typeof(x) _ret = (x); if (! _ret) { pr_notice("value is NULL at %s %s L %d\n", __FILE__, __FUNCTION__, __LINE__); dump_stack(); } return _ret; } while (0)
#define WC_DEBUG_PR_VOID_RET do { pr_notice("return at %s %s L %d\n", __FILE__, __FUNCTION__, __LINE__); dump_stack(); return; } while (0)
#define WC_DEBUG_PR_CODEPOINT() pr_notice("codepoint at %s %s L %d\n", __FILE__, __FUNCTION__, __LINE__)
#define WC_DEBUG_PR_CODEPOINT_VAL(val) pr_notice("codepoint at %s %s L %d, val %d\n", __FILE__, __FUNCTION__, __LINE__, val)
#define WC_DEBUG_PR(fmt, ...) pr_notice("%s %s L %d: " fmt, __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__)

#else
Expand All @@ -79,6 +81,7 @@
#define WC_DEBUG_PR_NULL_RET(x) return(x)
#define WC_DEBUG_PR_VOID_RET return
#define WC_DEBUG_PR_CODEPOINT() WC_DO_NOTHING
#define WC_DEBUG_PR_CODEPOINT_VAL(val) WC_DO_NOTHING
#define WC_DEBUG_PR(fmt, ...) WC_DO_NOTHING

#endif
Expand Down Expand Up @@ -183,18 +186,6 @@ static inline u32 wc_3u32_keyed_hash(const byte *key, const size_t key_len, u32
return wc_u32_keyed_hash(key, key_len, (byte *)&ubuf, sizeof(ubuf));
}

extern int wc_AesGcm_Appended_Tag_Encrypt(Aes* aes, byte* out, word32 out_space,
const byte* in, word32 in_sz,
const byte* iv, word32 iv_sz,
const byte* authIn, word32 authIn_sz,
const word32 authtag_len);

extern int wc_AesGcm_Appended_Tag_Decrypt(Aes* aes, byte* out, word32 out_space,
const byte* in, word32 in_sz,
const byte* iv, word32 iv_sz,
const byte* authIn, word32 authIn_sz,
const word32 authtag_len);

extern int wc_AesGcm_oneshot_encrypt(byte* out, size_t out_space, const byte* key, size_t keySz, const byte* in, size_t inSz,
const byte* iv, size_t ivSz,
const byte* authIn, size_t authInSz, size_t authTagSz);
Expand Down