/** * \brief Creates a new SymmetricState object. * * \param state Points to the variable where to store the pointer to * the new SymmetricState object. * \param name The name of the Noise protocol to use. This string * must be NUL-terminated. * \param id The protocol identifier as a set of algorithm identifiers. * * This is the internal implementation of noise_symmetricstate_new_by_id() * and noise_symmetricstate_new_by_name(). */ static int noise_symmetricstate_new (NoiseSymmetricState **state, const char *name, const NoiseProtocolId *id) { NoiseSymmetricState *new_state; size_t name_len; size_t hash_len; int err; /* Construct a state object and initialize it */ new_state = noise_new(NoiseSymmetricState); if (!new_state) return NOISE_ERROR_NO_MEMORY; new_state->id = *id; err = noise_cipherstate_new_by_id(&(new_state->cipher), id->cipher_id); if (err != NOISE_ERROR_NONE) { noise_symmetricstate_free(new_state); return err; } err = noise_hashstate_new_by_id(&(new_state->hash), id->hash_id); if (err != NOISE_ERROR_NONE) { noise_symmetricstate_free(new_state); return err; } /* Check the hash length against the maximum, just in case someone adds a new hash algorithm in the future with longer output. If this happens, modify NOISE_MAX_HASHLEN in internal.h accordingly */ hash_len = noise_hashstate_get_hash_length(new_state->hash); if (hash_len > NOISE_MAX_HASHLEN) { noise_symmetricstate_free(new_state); return NOISE_ERROR_INVALID_LENGTH; } /* The key length must also be less than or equal to the hash length */ if (noise_cipherstate_get_key_length(new_state->cipher) > hash_len) { noise_symmetricstate_free(new_state); return NOISE_ERROR_INVALID_LENGTH; } /* Initialize the chaining key "ck" and the handshake hash "h" from the protocol name. If the name is too long, hash it down first */ name_len = strlen(name); if (name_len <= hash_len) { memcpy(new_state->h, name, name_len); memset(new_state->h + name_len, 0, hash_len - name_len); } else { noise_hashstate_hash_one (new_state->hash, (const uint8_t *)name, name_len, new_state->h, hash_len); } memcpy(new_state->ck, new_state->h, hash_len); /* Ready to go */ *state = new_state; return NOISE_ERROR_NONE; }
/** * \brief Creates a new CipherState object by its algorithm name. * * \param state Points to the variable where to store the pointer to * the new CipherState object. * \param name The name of the cipher algorithm; e.g. "ChaChaPoly". * This string must be NUL-terminated. * * \return NOISE_ERROR_NONE on success. * \return NOISE_ERROR_INVALID_PARAM if \a state or \a name is NULL. * \return NOISE_ERROR_UNKNOWN_NAME if \a name is unknown. * \return NOISE_ERROR_NO_MEMORY if there is insufficient memory to * allocate the new CipherState object. * * \sa noise_cipherstate_free(), noise_cipherstate_new_by_id() */ int noise_cipherstate_new_by_name(NoiseCipherState **state, const char *name) { int id; /* The "state" and "name" arguments must be non-NULL */ if (!state) return NOISE_ERROR_INVALID_PARAM; *state = 0; if (!name) return NOISE_ERROR_INVALID_PARAM; /* Map the name and create the corresponding object */ id = noise_name_to_id(NOISE_CIPHER_CATEGORY, name, strlen(name)); if (id) return noise_cipherstate_new_by_id(state, id); /* We don't know what this is */ return NOISE_ERROR_UNKNOWN_NAME; }
/* Measure the performance of an AEAD primitive */ static void perf_cipher(int id) { static uint8_t const key[32] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 }; static uint8_t const ad[32] = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40 }; NoiseCipherState *cipher; uint8_t data[BLOCK_SIZE + 16]; timestamp_t start, end; int count; double elapsed; NoiseBuffer mbuf; if (noise_cipherstate_new_by_id(&cipher, id) != NOISE_ERROR_NONE) return; memset(data, 0xAA, sizeof(data)); noise_cipherstate_init_key(cipher, key, sizeof(key)); start = current_timestamp(); for (count = 0; count < (MB_COUNT * BLOCKS_PER_MB); ++count) { noise_buffer_set_inout(mbuf, data, sizeof(data) - 16, sizeof(data)); noise_cipherstate_encrypt_with_ad(cipher, ad, sizeof(ad), &mbuf); } end = current_timestamp(); elapsed = elapsed_to_seconds(start, end) / (double)MB_COUNT; printf("%-20s%8.2f %8.2f\n", noise_id_to_name(NOISE_CIPHER_CATEGORY, id), 1.0 / elapsed, units / elapsed); noise_cipherstate_free(cipher); }