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

Implement cipherstate rekey. #61

Open
wants to merge 2 commits into
base: master
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/cipherstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ int noise_cipherstate_decrypt(NoiseCipherState *state, NoiseBuffer *buffer);
int noise_cipherstate_set_nonce(NoiseCipherState *state, uint64_t nonce);
int noise_cipherstate_get_max_key_length(void);
int noise_cipherstate_get_max_mac_length(void);
int noise_cipherstate_rekey(NoiseCipherState* state);

#ifdef __cplusplus
};
Expand Down
31 changes: 31 additions & 0 deletions src/protocol/cipherstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,4 +554,35 @@ int noise_cipherstate_get_max_mac_length(void)
return NOISE_MAX_MAC_LEN;
}

/**
* \brief Rekeys the cipherstate as described in Noise protocol spec section 4.2.
*/
int noise_cipherstate_rekey(NoiseCipherState* state)
{
int err;
uint64_t n;
uint8_t new_key[NOISE_MAX_KEY_LEN + NOISE_MAX_MAC_LEN];
if (!state)
return NOISE_ERROR_INVALID_STATE;
if (!state->has_key)
return NOISE_ERROR_INVALID_STATE;

memset(new_key, 0, sizeof(new_key));

/* we call encrypt with max nonce, then reset to the current value */
n = state->n;
state->n = 0xFFFFFFFFFFFFFFFFULL;

/* Encrypt the plaintext and authenticate it */
err = (*(state->encrypt))(state, NULL, 0, new_key, state->key_len);
state->n = n;

if (err != NOISE_ERROR_NONE)
return err;

(*(state->init_key))(state, new_key);

return NOISE_ERROR_NONE;
}

/**@}*/
4 changes: 4 additions & 0 deletions tests/unit/test-cipherstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ static void check_cipher(int id, size_t key_len, size_t mac_len,
to encrypt one more block, and then the next request will be rejected */
compare(noise_cipherstate_set_nonce(state, 0xFFFFFFFFFFFFFFFEULL),
NOISE_ERROR_NONE);
/* Rekey, which should not affect the nonce and should still allow us to
encrypt one more block. */
compare(noise_cipherstate_rekey(state),
NOISE_ERROR_NONE);
noise_buffer_set_inout(mbuf, buffer, pt_len, sizeof(buffer));
compare(noise_cipherstate_encrypt_with_ad(state, a, ad_len, &mbuf),
NOISE_ERROR_NONE);
Expand Down