diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 9fc108b40..11e735a37 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -1622,7 +1622,7 @@ METHOD(message_t, generate, status_t, htoun32(lenpos, chunk.len + encryption->get_length(encryption)); } this->payloads->insert_last(this->payloads, encryption); - if (encryption->encrypt(encryption, chunk) != SUCCESS) + if (encryption->encrypt(encryption, this->message_id, chunk) != SUCCESS) { generator->destroy(generator); return INVALID_STATE; diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c index 6ba1b23a0..6a9f9c3bd 100644 --- a/src/libcharon/encoding/payloads/encryption_payload.c +++ b/src/libcharon/encoding/payloads/encryption_payload.c @@ -309,10 +309,11 @@ static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc) } METHOD(encryption_payload_t, encrypt, status_t, - private_encryption_payload_t *this, chunk_t assoc) + private_encryption_payload_t *this, u_int64_t mid, chunk_t assoc) { chunk_t iv, plain, padding, icv, crypt; generator_t *generator; + iv_gen_t *iv_gen; rng_t *rng; size_t bs; @@ -329,6 +330,13 @@ METHOD(encryption_payload_t, encrypt, status_t, return NOT_SUPPORTED; } + iv_gen = this->aead->get_iv_gen(this->aead); + if (!iv_gen) + { + DBG1(DBG_ENC, "encrypting encryption payload failed, no IV generator"); + return NOT_SUPPORTED; + } + assoc = append_header(this, assoc); generator = generator_create(); @@ -356,7 +364,7 @@ METHOD(encryption_payload_t, encrypt, status_t, crypt = chunk_create(plain.ptr, plain.len + padding.len); generator->destroy(generator); - if (!rng->get_bytes(rng, iv.len, iv.ptr) || + if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) || !rng->get_bytes(rng, padding.len - 1, padding.ptr)) { DBG1(DBG_ENC, "encrypting encryption payload failed, no IV or padding"); @@ -388,7 +396,7 @@ METHOD(encryption_payload_t, encrypt, status_t, } METHOD(encryption_payload_t, encrypt_v1, status_t, - private_encryption_payload_t *this, chunk_t iv) + private_encryption_payload_t *this, u_int64_t mid, chunk_t iv) { generator_t *generator; chunk_t plain, padding; diff --git a/src/libcharon/encoding/payloads/encryption_payload.h b/src/libcharon/encoding/payloads/encryption_payload.h index 5c6069339..f4fc7d667 100644 --- a/src/libcharon/encoding/payloads/encryption_payload.h +++ b/src/libcharon/encoding/payloads/encryption_payload.h @@ -71,13 +71,15 @@ struct encryption_payload_t { /** * Generate, encrypt and sign contained payloads. * + * @param mid message ID * @param assoc associated data * @return * - SUCCESS if encryption successful * - FAILED if encryption failed * - INVALID_STATE if aead not supplied, but needed */ - status_t (*encrypt) (encryption_payload_t *this, chunk_t assoc); + status_t (*encrypt) (encryption_payload_t *this, u_int64_t mid, + chunk_t assoc); /** * Decrypt, verify and parse contained payloads. diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c index 39e4cad20..bf1b0046c 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.c +++ b/src/libcharon/sa/ikev1/keymat_v1.c @@ -196,6 +196,13 @@ METHOD(aead_t, get_iv_size, size_t, return 0; } +METHOD(aead_t, get_iv_gen, iv_gen_t*, + private_aead_t *this) +{ + /* IVs are retrieved via keymat_v1.get_iv() */ + return NULL; +} + METHOD(aead_t, get_key_size, size_t, private_aead_t *this) { @@ -304,6 +311,7 @@ static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e) .get_block_size = _get_block_size, .get_icv_size = _get_icv_size, .get_iv_size = _get_iv_size, + .get_iv_gen = _get_iv_gen, .get_key_size = _get_key_size, .set_key = _set_key, .destroy = _aead_destroy, diff --git a/src/libipsec/esp_packet.c b/src/libipsec/esp_packet.c index 61389daa4..db5ef3685 100644 --- a/src/libipsec/esp_packet.c +++ b/src/libipsec/esp_packet.c @@ -283,7 +283,7 @@ METHOD(esp_packet_t, encrypt, status_t, u_int32_t next_seqno; size_t blocksize, plainlen; aead_t *aead; - rng_t *rng; + iv_gen_t *iv_gen; this->packet->set_data(this->packet, chunk_empty); @@ -293,13 +293,13 @@ METHOD(esp_packet_t, encrypt, status_t, return FAILED; } - rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); - if (!rng) + aead = esp_context->get_aead(esp_context); + iv_gen = aead->get_iv_gen(aead); + if (!iv_gen) { - DBG1(DBG_ESP, "ESP encryption failed: could not find RNG"); + DBG1(DBG_ESP, "ESP encryption failed: no IV generator"); return NOT_FOUND; } - aead = esp_context->get_aead(esp_context); blocksize = aead->get_block_size(aead); iv.len = aead->get_iv_size(aead); @@ -319,14 +319,12 @@ METHOD(esp_packet_t, encrypt, status_t, writer->write_uint32(writer, next_seqno); iv = writer->skip(writer, iv.len); - if (!rng->get_bytes(rng, iv.len, iv.ptr)) + if (!iv_gen->get_iv(iv_gen, next_seqno, iv.len, iv.ptr)) { DBG1(DBG_ESP, "ESP encryption failed: could not generate IV"); writer->destroy(writer); - rng->destroy(rng); return FAILED; } - rng->destroy(rng); /* plain-/ciphertext will start here */ ciphertext = writer->get_buf(writer); diff --git a/src/libipsec/esp_packet.h b/src/libipsec/esp_packet.h index ce8645825..f1941a3ba 100644 --- a/src/libipsec/esp_packet.h +++ b/src/libipsec/esp_packet.h @@ -91,7 +91,7 @@ struct esp_packet_t { * @return - SUCCESS if encrypted * - FAILED if sequence number cycled or any of the * cryptographic functions failed - * - NOT_FOUND if no suitable RNG could be found + * - NOT_FOUND if no suitable IV generator provided */ status_t (*encrypt)(esp_packet_t *this, esp_context_t *esp_context, u_int32_t spi); diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index 74b409608..1a13fdd71 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -13,6 +13,7 @@ crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \ crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ +crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \ credentials/credential_factory.c credentials/builder.c \ credentials/cred_encoding.c credentials/keys/private_key.c \ credentials/keys/public_key.c credentials/keys/shared_key.c \ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 54b19e139..677701c00 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -11,6 +11,7 @@ crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \ crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ +crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \ credentials/credential_factory.c credentials/builder.c \ credentials/cred_encoding.c credentials/keys/private_key.c \ credentials/keys/public_key.c credentials/keys/shared_key.c \ @@ -47,7 +48,7 @@ crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \ crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \ crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \ crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \ -crypto/aead.h crypto/transform.h crypto/pkcs5.h \ +crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \ credentials/credential_factory.h credentials/builder.h \ credentials/cred_encoding.h credentials/keys/private_key.h \ credentials/keys/public_key.h credentials/keys/shared_key.h \ diff --git a/src/libstrongswan/crypto/aead.c b/src/libstrongswan/crypto/aead.c index 32a0e6759..afcc11fbe 100644 --- a/src/libstrongswan/crypto/aead.c +++ b/src/libstrongswan/crypto/aead.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -16,6 +19,7 @@ #include "aead.h" #include +#include typedef struct private_aead_t private_aead_t; @@ -35,9 +39,14 @@ struct private_aead_t { crypter_t *crypter; /** - * draditional signer + * traditional signer */ signer_t *signer; + + /** + * IV generator + */ + iv_gen_t *iv_gen; }; METHOD(aead_t, encrypt, bool, @@ -126,6 +135,12 @@ METHOD(aead_t, get_iv_size, size_t, return this->crypter->get_iv_size(this->crypter); } +METHOD(aead_t, get_iv_gen, iv_gen_t*, + private_aead_t *this) +{ + return this->iv_gen; +} + METHOD(aead_t, get_key_size, size_t, private_aead_t *this) { @@ -148,6 +163,7 @@ METHOD(aead_t, set_key, bool, METHOD(aead_t, destroy, void, private_aead_t *this) { + this->iv_gen->destroy(this->iv_gen); this->crypter->destroy(this->crypter); this->signer->destroy(this->signer); free(this); @@ -167,12 +183,14 @@ aead_t *aead_create(crypter_t *crypter, signer_t *signer) .get_block_size = _get_block_size, .get_icv_size = _get_icv_size, .get_iv_size = _get_iv_size, + .get_iv_gen = _get_iv_gen, .get_key_size = _get_key_size, .set_key = _set_key, .destroy = _destroy, }, .crypter = crypter, .signer = signer, + .iv_gen = iv_gen_rand_create(), ); return &this->public; diff --git a/src/libstrongswan/crypto/aead.h b/src/libstrongswan/crypto/aead.h index f3959f8f3..c887f53bb 100644 --- a/src/libstrongswan/crypto/aead.h +++ b/src/libstrongswan/crypto/aead.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -26,6 +29,7 @@ typedef struct aead_t aead_t; #include #include #include +#include /** * Authenticated encryption / authentication decryption interface. @@ -88,6 +92,13 @@ struct aead_t { */ size_t (*get_iv_size)(aead_t *this); + /** + * Get the IV generator implementation + * + * @return IV generator + */ + iv_gen_t *(*get_iv_gen)(aead_t *this); + /** * Get the size of the key material (for encryption and authentication). * diff --git a/src/libstrongswan/crypto/iv/iv_gen.h b/src/libstrongswan/crypto/iv/iv_gen.h new file mode 100644 index 000000000..f6bc6471f --- /dev/null +++ b/src/libstrongswan/crypto/iv/iv_gen.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup iv iv + * @{ @ingroup crypto + */ + +#ifndef IV_GEN_H_ +#define IV_GEN_H_ + +typedef struct iv_gen_t iv_gen_t; + +#include + +/** + * Generic interface for initialization vector (IV) generators. + */ +struct iv_gen_t { + + /** + * Generates an IV and writes it into the buffer. + * + * @param seq external sequence number + * @param size size of IV in bytes + * @param buffer pointer where the generated IV will be written + * @return TRUE if IV allocation was successful, FALSE otherwise + */ + bool (*get_iv)(iv_gen_t *this, u_int64_t seq, size_t size, + u_int8_t *buffer) __attribute__((warn_unused_result)); + + /** + * Generates an IV and allocates space for it. + * + * @param seq external sequence number + * @param size size of IV in bytes + * @param chunk chunk which will hold the generated IV + * @return TRUE if IV allocation was successful, FALSE otherwise + */ + bool (*allocate_iv)(iv_gen_t *this, u_int64_t seq, size_t size, + chunk_t *chunk) __attribute__((warn_unused_result)); + + /** + * Destroys an IV generator object. + */ + void (*destroy)(iv_gen_t *this); +}; + +#endif /** IV_GEN_H_ @}*/ diff --git a/src/libstrongswan/crypto/iv/iv_gen_rand.c b/src/libstrongswan/crypto/iv/iv_gen_rand.c new file mode 100644 index 000000000..2bed63fcc --- /dev/null +++ b/src/libstrongswan/crypto/iv/iv_gen_rand.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "iv_gen_rand.h" + +#include + +typedef struct private_iv_gen_t private_iv_gen_t; + +/** + * Private data of an iv_gen_t object. + */ +struct private_iv_gen_t { + + /** + * Public iv_gen_t interface. + */ + iv_gen_t public; + + /** + * rng_t object + */ + rng_t *rng; +}; + +METHOD(iv_gen_t, get_iv, bool, + private_iv_gen_t *this, u_int64_t seq, size_t size, u_int8_t *buffer) +{ + if (!this->rng) + { + return FALSE; + } + return this->rng->get_bytes(this->rng, size, buffer); +} + +METHOD(iv_gen_t, allocate_iv, bool, + private_iv_gen_t *this, u_int64_t seq, size_t size, chunk_t *chunk) +{ + if (!this->rng) + { + return FALSE; + } + return this->rng->allocate_bytes(this->rng, size, chunk); +} + +METHOD(iv_gen_t, destroy, void, + private_iv_gen_t *this) +{ + DESTROY_IF(this->rng); + free(this); +} + +iv_gen_t *iv_gen_rand_create() +{ + private_iv_gen_t *this; + + INIT(this, + .public = { + .get_iv = _get_iv, + .allocate_iv = _allocate_iv, + .destroy = _destroy, + }, + .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK), + ); + + return &this->public; +} diff --git a/src/libstrongswan/crypto/iv/iv_gen_rand.h b/src/libstrongswan/crypto/iv/iv_gen_rand.h new file mode 100644 index 000000000..62d76ed21 --- /dev/null +++ b/src/libstrongswan/crypto/iv/iv_gen_rand.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @{ @ingroup iv + */ + +#ifndef IV_GEN_RAND_H_ +#define IV_GEN_RAND_H_ + +#include + +/** + * Create an IV generator that generates random IVs. + * + * @return IV generator + */ +iv_gen_t *iv_gen_rand_create(); + +#endif /** IV_GEN_RAND_H_ @}*/ diff --git a/src/libstrongswan/crypto/iv/iv_gen_seq.c b/src/libstrongswan/crypto/iv/iv_gen_seq.c new file mode 100644 index 000000000..98d0c15a6 --- /dev/null +++ b/src/libstrongswan/crypto/iv/iv_gen_seq.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "iv_gen_seq.h" + +typedef struct private_iv_gen_t private_iv_gen_t; + +/** + * Private data of an iv_gen_t object. + */ +struct private_iv_gen_t { + + /** + * Public iv_gen_t interface. + */ + iv_gen_t public; + + /** + * Salt to mask counter + */ + u_int8_t *salt; +}; + +METHOD(iv_gen_t, get_iv, bool, + private_iv_gen_t *this, u_int64_t seq, size_t size, u_int8_t *buffer) +{ + u_int8_t iv[sizeof(u_int64_t)]; + size_t len = size; + + if (!this->salt) + { + return FALSE; + } + if (len > sizeof(u_int64_t)) + { + len = sizeof(u_int64_t); + memset(buffer, 0, size - len); + } + htoun64(iv, seq); + memxor(iv, this->salt, sizeof(u_int64_t)); + memcpy(buffer + size - len, iv + sizeof(u_int64_t) - len, len); + return TRUE; +} + +METHOD(iv_gen_t, allocate_iv, bool, + private_iv_gen_t *this, u_int64_t seq, size_t size, chunk_t *chunk) +{ + *chunk = chunk_alloc(size); + if (!get_iv(this, seq, chunk->len, chunk->ptr)) + { + chunk_free(chunk); + return FALSE; + } + return TRUE; +} + +METHOD(iv_gen_t, destroy, void, + private_iv_gen_t *this) +{ + free(this->salt); + free(this); +} + +iv_gen_t *iv_gen_seq_create() +{ + private_iv_gen_t *this; + rng_t *rng; + + INIT(this, + .public = { + .get_iv = _get_iv, + .allocate_iv = _allocate_iv, + .destroy = _destroy, + }, + ); + + rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); + if (rng) + { + this->salt = malloc(sizeof(u_int64_t)); + if (!rng->get_bytes(rng, sizeof(u_int64_t), this->salt)) + { + free(this->salt); + this->salt = NULL; + } + rng->destroy(rng); + } + + return &this->public; +} diff --git a/src/libstrongswan/crypto/iv/iv_gen_seq.h b/src/libstrongswan/crypto/iv/iv_gen_seq.h new file mode 100644 index 000000000..329dcca05 --- /dev/null +++ b/src/libstrongswan/crypto/iv/iv_gen_seq.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @{ @ingroup iv + */ + +#ifndef IV_GEN_SEQ_H_ +#define IV_GEN_SEQ_H_ + +#include + +/** + * Create an IV generator that generates sequential IVs (counter). + * + * @return IV generator + */ +iv_gen_t *iv_gen_seq_create(); + +#endif /** IV_GEN_SEQ_H_ @}*/ diff --git a/src/libstrongswan/crypto/prfs/mac_prf.h b/src/libstrongswan/crypto/prfs/mac_prf.h index b2c0c6e17..4ff925b04 100644 --- a/src/libstrongswan/crypto/prfs/mac_prf.h +++ b/src/libstrongswan/crypto/prfs/mac_prf.h @@ -15,7 +15,7 @@ /** * @defgroup mac_prf mac_prf - * @{ @ingroup crypto + * @{ @ingroup prf */ #ifndef MAC_PRF_H_ diff --git a/src/libstrongswan/plugins/ccm/ccm_aead.c b/src/libstrongswan/plugins/ccm/ccm_aead.c index 0e2f9b75f..f5ad606b7 100644 --- a/src/libstrongswan/plugins/ccm/ccm_aead.c +++ b/src/libstrongswan/plugins/ccm/ccm_aead.c @@ -15,6 +15,8 @@ #include "ccm_aead.h" +#include + #define BLOCK_SIZE 16 #define SALT_SIZE 3 #define IV_SIZE 8 @@ -38,6 +40,11 @@ struct private_ccm_aead_t { */ crypter_t *crypter; + /** + * IV generator. + */ + iv_gen_t *iv_gen; + /** * Length of the integrity check value */ @@ -305,6 +312,12 @@ METHOD(aead_t, get_iv_size, size_t, return IV_SIZE; } +METHOD(aead_t, get_iv_gen, iv_gen_t* + private_ccm_aead_t *this) +{ + return this->iv_gen; +} + METHOD(aead_t, get_key_size, size_t, private_ccm_aead_t *this) { @@ -323,6 +336,7 @@ METHOD(aead_t, destroy, void, private_ccm_aead_t *this) { this->crypter->destroy(this->crypter); + this->iv_gen->destroy(this->iv_gen); free(this); } @@ -384,12 +398,14 @@ ccm_aead_t *ccm_aead_create(encryption_algorithm_t algo, size_t key_size) .get_block_size = _get_block_size, .get_icv_size = _get_icv_size, .get_iv_size = _get_iv_size, + .get_iv_gen = _get_iv_gen, .get_key_size = _get_key_size, .set_key = _set_key, .destroy = _destroy, }, }, .crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size), + .iv_gen = iv_gen_seq_create(), .icv_size = icv_size, ); diff --git a/src/libstrongswan/plugins/gcm/gcm_aead.c b/src/libstrongswan/plugins/gcm/gcm_aead.c index 79ee65d98..ba5f2e4b3 100644 --- a/src/libstrongswan/plugins/gcm/gcm_aead.c +++ b/src/libstrongswan/plugins/gcm/gcm_aead.c @@ -16,6 +16,7 @@ #include "gcm_aead.h" #include +#include #define BLOCK_SIZE 16 #define NONCE_SIZE 12 @@ -39,6 +40,11 @@ struct private_gcm_aead_t { */ crypter_t *crypter; + /** + * IV generator. + */ + iv_gen_t *iv_gen; + /** * Size of the integrity check value */ @@ -337,6 +343,12 @@ METHOD(aead_t, get_iv_size, size_t, return IV_SIZE; } +METHOD(aead_t, get_iv_gen, iv_gen_t*, + private_gcm_aead_t *this) +{ + return this->iv_gen; +} + METHOD(aead_t, get_key_size, size_t, private_gcm_aead_t *this) { @@ -356,6 +368,7 @@ METHOD(aead_t, destroy, void, private_gcm_aead_t *this) { this->crypter->destroy(this->crypter); + this->iv_gen->destroy(this->iv_gen); free(this); } @@ -405,12 +418,14 @@ gcm_aead_t *gcm_aead_create(encryption_algorithm_t algo, size_t key_size) .get_block_size = _get_block_size, .get_icv_size = _get_icv_size, .get_iv_size = _get_iv_size, + .get_iv_gen = _get_iv_gen, .get_key_size = _get_key_size, .set_key = _set_key, .destroy = _destroy, }, }, .crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size), + .iv_gen = iv_gen_seq_create(), .icv_size = icv_size, ); diff --git a/src/libstrongswan/plugins/openssl/openssl_gcm.c b/src/libstrongswan/plugins/openssl/openssl_gcm.c index 89d1cd589..842111bd3 100644 --- a/src/libstrongswan/plugins/openssl/openssl_gcm.c +++ b/src/libstrongswan/plugins/openssl/openssl_gcm.c @@ -20,6 +20,7 @@ #include "openssl_gcm.h" #include +#include /** as defined in RFC 4106 */ #define IV_LEN 8 @@ -53,6 +54,11 @@ struct private_aead_t { */ size_t icv_size; + /** + * IV generator + */ + iv_gen_t *iv_gen; + /** * The cipher to use */ @@ -161,6 +167,12 @@ METHOD(aead_t, get_iv_size, size_t, return IV_LEN; } +METHOD(aead_t, get_iv_gen, iv_gen_t*, + private_aead_t *this) +{ + return this->iv_gen; +} + METHOD(aead_t, get_key_size, size_t, private_aead_t *this) { @@ -183,6 +195,7 @@ METHOD(aead_t, destroy, void, private_aead_t *this) { chunk_clear(&this->key); + this->iv_gen->destroy(this->iv_gen); free(this); } @@ -200,6 +213,7 @@ aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size) .get_block_size = _get_block_size, .get_icv_size = _get_icv_size, .get_iv_size = _get_iv_size, + .get_iv_gen = _get_iv_gen, .get_key_size = _get_key_size, .set_key = _set_key, .destroy = _destroy, @@ -258,6 +272,7 @@ aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size) } this->key = chunk_alloc(key_size); + this->iv_gen = iv_gen_seq_create(); return &this->public; }