Example #1
0
/**
 * \brief Encrypts or decrypts a block.
 *
 * \param st The cipher state for AESGCM.
 * \param data The data to be encrypted or decrypted.
 * \param len The length of the data to be encrypted or decrypted in bytes.
 */
static void noise_aesgcm_encrypt_or_decrypt
    (NoiseAESGCMState *st, uint8_t *data, size_t len)
{
    uint8_t temp, index;
    uint8_t keystream[16];
    while (len > 0) {
        /* Increment the counter block and encrypt to get keystream data.
           We only need to increment the last two bytes of the counter
           because the maximum payload size of 65535 bytes means a maximum
           counter value of 4097 (+1 for the hashing nonce) */
        uint16_t counter = (((uint16_t)(st->counter[15])) |
                           (((uint16_t)(st->counter[14])) << 8)) + 1;
        st->counter[15] = (uint8_t)counter;
        st->counter[14] = (uint8_t)(counter >> 8);
        rijndaelEncrypt(st->aes, MAXNR, st->counter, keystream);

        /* XOR the input with the keystream block to generate the output */
        temp = 16;
        if (temp > len)
            temp = len;
        for (index = 0; index < temp; ++index)
            data[index] ^= keystream[index];
        data += temp;
        len -= temp;
    }
    noise_clean(keystream, sizeof(keystream));
}
Example #2
0
/**
 * \brief Forces a rekey on the random number generator.
 *
 * \param state The state of the random number generator.
 */
static void noise_randstate_rekey(NoiseRandState *state)
{
    uint8_t data[40];
    memset(data, 0, sizeof(data));
    chacha_encrypt_bytes(&(state->chacha), data, data, sizeof(data));
    chacha_keysetup(&(state->chacha), data, 256);
    chacha_ivsetup(&(state->chacha), data + 32, 0);
    noise_clean(data, sizeof(data));
}
Example #3
0
/**
 * \brief Decrypts a block of data with this SymmetricState object
 * and adds the ciphertext to the handshake hash.
 *
 * \param state The SymmetricState object.
 * \param buffer The buffer containing the ciphertext plus MAC on entry
 * and the plaintext on exit.
 *
 * \return NOISE_ERROR_NONE on success.
 * \return NOISE_ERROR_INVALID_PARAM if \a state or \a buffer is NULL.
 * \return NOISE_ERROR_MAC_FAILURE if the MAC check failed.
 * \return NOISE_ERROR_INVALID_STATE if this SymmetricState has
 * already been split.
 * \return NOISE_ERROR_INVALID_NONCE if the nonce previously overflowed.
 * \return NOISE_ERROR_INVALID_LENGTH if the data in \a buffer is
 * larger than 65535 bytes or too small to contain the MAC value.
 *
 * The ciphertext is decrypted in-place with the plaintext also written
 * to \a buffer.  In other words, it is assumed that the ciphertext plus
 * MAC is in an input buffer ready to be processed once the MAC has
 * been checked and the ciphertext has been decrypted.
 *
 * \sa noise_symmetricstate_encrypt_and_hash()
 */
int noise_symmetricstate_decrypt_and_hash
    (NoiseSymmetricState *state, NoiseBuffer *buffer)
{
    uint8_t temp[NOISE_MAX_HASHLEN];
    size_t hash_len;
    int err;

    /* Validate the parameters */
    if (!state || !buffer || !(buffer->data))
        return NOISE_ERROR_INVALID_PARAM;

    /* If the state has been split, then we cannot do this */
    if (!state->cipher)
        return NOISE_ERROR_INVALID_STATE;

    /* Validate the input data length before we hash the data */
    if (buffer->size > NOISE_MAX_PAYLOAD_LEN)
        return NOISE_ERROR_INVALID_LENGTH;
    if (noise_cipherstate_has_key(state->cipher)) {
        if (buffer->size < noise_cipherstate_get_mac_length(state->cipher))
            return NOISE_ERROR_INVALID_LENGTH;
    }

    /* Feed the ciphertext into the handshake hash first.  We make a
       temporary copy of the hash.  If the decryption fails below,
       then we don't update the handshake hash with the bogus data */
    hash_len = noise_hashstate_get_hash_length(state->hash);
    noise_hashstate_hash_two
        (state->hash, state->h, hash_len,
         buffer->data, buffer->size, temp, hash_len);

    /* Decrypt the ciphertext using the underlying cipher */
    err = noise_cipherstate_decrypt_with_ad
        (state->cipher, state->h, hash_len, buffer);
    if (err != NOISE_ERROR_NONE) {
        noise_clean(temp, sizeof(temp));
        return err;
    }

    /* Update the handshake hash */
    memcpy(state->h, temp, hash_len);
    noise_clean(temp, sizeof(temp));
    return NOISE_ERROR_NONE;
}
/* ************************************************** */
void do_clean(void) {
    rng_clean();                   /* rng        */
    scheduler_clean();             /* scheduler  */
    packet_clean();                /* packet     */
    noise_clean();                 /* noise      */
    node_clean();                  /* node       */
    modulation_clean();            /* modulation */
    mobility_clean();              /* mobility   */
    medium_clean();                /* medium     */
    measure_clean();               /* measure    */
    monitor_clean();               /* monitor    */
    entity_clean();                /* entity     */
    bundle_clean();                /* bundler    */
    timer_clean();                 /* timer      */
    mem_fs_clean();                /* mem_fs     */
}
Example #5
0
/**
 * \brief Splits the transport encryption CipherState objects out of
 * this SymmetricState object.
 *
 * \param state The SymmetricState object.
 * \param c1 Points to the variable where to place the pointer to the
 * first CipherState object.  This can be NULL if the application is
 * using a one-way handshake pattern.
 * \param c2 Points to the variable where to place the pointer to the
 * second CipherState object.  This can be NULL if the application is
 * using a one-way handshake pattern.
 * \param secondary_key Points to an optional "secondary symmetric key"
 * from a parallel non-DH handshake to mix into the final cipher keys.
 * This may be NULL if \a secondary_key_len is zero.
 * \param secondary_key_len Length of \a secondary_key in bytes.
 * This must be either zero or 32 to comply with the requirements from
 * the Noise protocol specification.
 *
 * \return NOISE_ERROR_NONE on success.
 * \return NOISE_ERROR_INVALID_PARAM if \a state is NULL.
 * \return NOISE_ERROR_INVALID_PARAM if both \a c1 and \a c2 are NULL.
 * \return NOISE_ERROR_INVALID_PARAM if \a secondary_key is NULL and
 * \a secondary_key_len is not zero.
 * \return NOISE_ERROR_INVALID_LENGTH if \a secondary_key_len is not zero or 32.
 * \return NOISE_ERROR_INVALID_STATE if the \a state has already been split.
 * \return NOISE_ERROR_NO_MEMORY if there is insufficient memory to create
 * the new CipherState objects.
 *
 * Once a SymmetricState has been split, it is effectively finished and
 * cannot be used for future encryption or hashing operations.
 * If those operations are invoked, the relevant functions will return
 * NOISE_ERROR_INVALID_STATE.
 *
 * The \a c1 object should be used to protect messages from the initiator to
 * the responder, and the \a c2 object should be used to protect messages
 * from the responder to the initiator.
 *
 * If the handshake pattern is one-way, then the application should call
 * noise_cipherstate_free() on the object that is not needed.  Alternatively,
 * the application can pass NULL to noise_symmetricstate_split() as the
 * \a c1 or \a c2 argument and the second CipherState will not be created
 * at all.
 */
int noise_symmetricstate_split
    (NoiseSymmetricState *state, NoiseCipherState **c1, NoiseCipherState **c2,
     const uint8_t *secondary_key, size_t secondary_key_len)
{
    uint8_t temp_k1[NOISE_MAX_HASHLEN];
    uint8_t temp_k2[NOISE_MAX_HASHLEN];
    size_t hash_len;
    size_t key_len;

    /* Validate the parameters */
    if (!state)
        return NOISE_ERROR_INVALID_PARAM;
    if (!c1 && !c2)
        return NOISE_ERROR_INVALID_PARAM;
    if (!secondary_key && secondary_key_len)
        return NOISE_ERROR_INVALID_PARAM;
    if (secondary_key_len != 0 && secondary_key_len != 32)
        return NOISE_ERROR_INVALID_LENGTH;
    if (c1)
        *c1 = 0;
    if (c2)
        *c2 = 0;

    /* If the state has already been split, then we cannot split again */
    if (!state->cipher)
        return NOISE_ERROR_INVALID_STATE;

    /* Generate the two encryption keys with HKDF */
    hash_len = noise_hashstate_get_hash_length(state->hash);
    key_len = noise_cipherstate_get_key_length(state->cipher);
    if (!secondary_key) {
        noise_hashstate_hkdf
            (state->hash, state->ck, hash_len, state->ck, 0,
             temp_k1, key_len, temp_k2, key_len);
    } else {
        noise_hashstate_hkdf
            (state->hash, state->ck, hash_len, secondary_key, secondary_key_len,
             temp_k1, key_len, temp_k2, key_len);
    }

    /* If we only need c2, then re-initialize the key in the internal
       cipher and copy it to c2 */
    if (!c1 && c2) {
        noise_cipherstate_init_key(state->cipher, temp_k2, key_len);
        *c2 = state->cipher;
        state->cipher = 0;
        noise_clean(temp_k1, sizeof(temp_k1));
        noise_clean(temp_k2, sizeof(temp_k2));
        return NOISE_ERROR_NONE;
    }

    /* Split a copy out of the cipher and give it the second key.
       We don't need to do this if the second CipherSuite is not required */
    if (c2) {
        *c2 = (*(state->cipher->create))();
        if (!(*c2)) {
            noise_clean(temp_k1, sizeof(temp_k1));
            noise_clean(temp_k2, sizeof(temp_k2));
            return NOISE_ERROR_NO_MEMORY;
        }
        noise_cipherstate_init_key(*c2, temp_k2, key_len);
    }

    /* Re-initialize the key in the internal cipher and copy it to c1 */
    noise_cipherstate_init_key(state->cipher, temp_k1, key_len);
    *c1 = state->cipher;
    state->cipher = 0;
    noise_clean(temp_k1, sizeof(temp_k1));
    noise_clean(temp_k2, sizeof(temp_k2));
    return NOISE_ERROR_NONE;
}