Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix PSK in rev32 #36

Open
wants to merge 2 commits into
base: rev32
Choose a base branch
from
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
1 change: 1 addition & 0 deletions include/noise/protocol/handshakestate.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ NoiseDHState *noise_handshakestate_get_fixed_ephemeral_dh
(NoiseHandshakeState *state);
NoiseDHState *noise_handshakestate_get_fixed_hybrid_dh
(NoiseHandshakeState *state);
int noise_handshakestate_needs_pre_shared_key(const NoiseHandshakeState *state);
int noise_handshakestate_has_pre_shared_key(const NoiseHandshakeState *state);
int noise_handshakestate_set_pre_shared_key
(NoiseHandshakeState *state, const uint8_t *key, size_t key_len);
Expand Down
42 changes: 41 additions & 1 deletion src/protocol/handshakestate.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ static int noise_handshakestate_new
num_modifiers = 0;
while (num_modifiers < NOISE_MAX_MODIFIER_IDS &&
symmetric->id.modifier_ids[num_modifiers] != 0) {
switch(symmetric->id.modifier_ids[num_modifiers]) {
case NOISE_MODIFIER_PSK0:
case NOISE_MODIFIER_PSK1:
case NOISE_MODIFIER_PSK2:
case NOISE_MODIFIER_PSK3:
extra_reqs |= NOISE_REQ_PSK;
break;
default:
break;
}
++num_modifiers;
}
if (noise_pattern_expand(tokens, symmetric->id.pattern_id,
Expand Down Expand Up @@ -533,6 +543,25 @@ NoiseDHState *noise_handshakestate_get_fixed_hybrid_dh
return state->dh_fixed_hybrid;
}

/**
* \brief Determine if a HandshakeState object requires a pre shared key.
*
* \param state The HandshakeState object.
*
* \return Returns 1 if \a state requires a pre shared key, zero if the
* pre shared key has already been supplied or it is not required.
*
* \sa noise_handshakestate_set_pre_shared_key(),
* noise_handshakestate_has_pre_shared_key()
*/
int noise_handshakestate_needs_pre_shared_key(const NoiseHandshakeState *state)
{
if (!state || state->pre_shared_key_len)
return 0;
else
return (state->requirements & NOISE_REQ_PSK) != 0;
}

/**
* \brief Determine if a HandshakeState object has already been configured
* with a pre shared key.
Expand All @@ -541,7 +570,8 @@ NoiseDHState *noise_handshakestate_get_fixed_hybrid_dh
*
* \return Returns 1 if \a state has a pre shared key, zero if not.
*
* \sa noise_handshakestate_set_pre_shared_key()
* \sa noise_handshakestate_set_pre_shared_key(),
* noise_handshakestate_needs_pre_shared_key()
*/
int noise_handshakestate_has_pre_shared_key(const NoiseHandshakeState *state)
{
Expand Down Expand Up @@ -569,6 +599,7 @@ int noise_handshakestate_has_pre_shared_key(const NoiseHandshakeState *state)
* then the value will be ignored.
*
* \sa noise_handshakestate_start(), noise_handshakestate_set_prologue(),
* noise_handshakestate_needs_pre_shared_key(),
* noise_handshakestate_has_pre_shared_key(),
* noise_handshakestate_set_pre_shared_key_hook()
*/
Expand Down Expand Up @@ -1213,6 +1244,9 @@ static int noise_handshakestate_write
return NOISE_ERROR_INVALID_LENGTH;
memcpy(rest.data, state->dh_local_ephemeral->public_key, len);
noise_symmetricstate_mix_hash(state->symmetric, rest.data, len);
if (state->requirements & NOISE_REQ_PSK) {
noise_symmetricstate_mix_key(state->symmetric, rest.data, len);
}
rest.size += len;
break;
case NOISE_TOKEN_S:
Expand Down Expand Up @@ -1476,6 +1510,12 @@ static int noise_handshakestate_read
(state->symmetric, msg.data, len);
if (err != NOISE_ERROR_NONE)
break;
if (state->requirements & NOISE_REQ_PSK) {
err = noise_symmetricstate_mix_key
(state->symmetric, msg.data, len);
if (err != NOISE_ERROR_NONE)
break;
}
err = noise_dhstate_set_public_key
(state->dh_remote_ephemeral, msg.data, len);
if (err != NOISE_ERROR_NONE)
Expand Down
10 changes: 6 additions & 4 deletions src/protocol/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -652,14 +652,16 @@ struct NoiseHandshakeState_s
#define NOISE_REQ_LOCAL_REQUIRED (1 << 0)
/** Remote public key is required for the handshake */
#define NOISE_REQ_REMOTE_REQUIRED (1 << 1)
/** Pre-shared key has not been provided yet */
#define NOISE_REQ_PSK (1 << 2)
/** Emphemeral key for fallback pre-message has been provided */
#define NOISE_REQ_FALLBACK_PREMSG (1 << 2)
#define NOISE_REQ_FALLBACK_PREMSG (1 << 3)
/** Local public key is part of the pre-message */
#define NOISE_REQ_LOCAL_PREMSG (1 << 3)
#define NOISE_REQ_LOCAL_PREMSG (1 << 4)
/** Remote public key is part of the pre-message */
#define NOISE_REQ_REMOTE_PREMSG (1 << 4)
#define NOISE_REQ_REMOTE_PREMSG (1 << 5)
/** Fallback is possible from this pattern (two-way, ends in "K") */
#define NOISE_REQ_FALLBACK_POSSIBLE (1 << 5)
#define NOISE_REQ_FALLBACK_POSSIBLE (1 << 6)

void noise_rand_bytes(void *bytes, size_t size);

Expand Down
8 changes: 8 additions & 0 deletions src/protocol/symmetricstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ int noise_symmetricstate_mix_key
(state->hash, state->ck, hash_len, input, size,
state->ck, hash_len, temp_k, key_len);

/* Truncate temp_k */
if (hash_len == 64 && key_len > 32)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would seem to prevent the use of symmetric ciphers with more than 256 bits. While the noise specification may have that restriction, I tried to avoid putting that restriction into the code to support future ciphers with larger keys. Why is this needed?

key_len = 32;

/* Change the cipher key, or set it for the first time */
noise_cipherstate_init_key(state->cipher, temp_k, key_len);
noise_clean(temp_k, sizeof(temp_k));
Expand Down Expand Up @@ -360,6 +364,10 @@ int noise_symmetricstate_mix_key_and_hash
noise_hashstate_hash_two
(state->hash, state->h, hash_len, temp_h, hash_len, state->h, hash_len);

/* Truncate temp_k */
if (hash_len == 64 && key_len > 32)
key_len = 32;

/* Change the cipher key, or set it for the first time */
noise_cipherstate_init_key(state->cipher, temp_k, key_len);
noise_clean(temp_h, sizeof(temp_h));
Expand Down