2 * Copyright (C) 2008 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "openssl_crypter.h"
18 #include <openssl/evp.h>
20 typedef struct private_openssl_crypter_t private_openssl_crypter_t
;
23 * Private data of openssl_crypter_t
25 struct private_openssl_crypter_t
{
28 * Public part of this class.
30 openssl_crypter_t
public;
40 const EVP_CIPHER
*cipher
;
44 * Look up an OpenSSL algorithm name and validate its key size
46 static char* lookup_algorithm(u_int16_t ikev2_algo
, size_t *key_size
)
49 /* identifier specified in IKEv2 */
51 /* name of the algorithm, as used in OpenSSL */
53 /* default key size in bytes */
55 /* minimum key size */
57 /* maximum key size */
60 {ENCR_DES
, "des", 8, 8, 8},
61 {ENCR_3DES
, "des3", 24, 24, 24},
62 {ENCR_RC5
, "rc5", 16, 5, 255},
63 {ENCR_IDEA
, "idea", 16, 16, 16},
64 {ENCR_CAST
, "cast", 16, 5, 16},
65 {ENCR_BLOWFISH
, "blowfish", 16, 5, 56},
69 for (i
= 0; i
< countof(mappings
); i
++)
71 if (ikev2_algo
== mappings
[i
].ikev2_id
)
73 /* set the key size if it is not set */
76 *key_size
= mappings
[i
].key_def
;
78 /* validate key size */
79 if (*key_size
< mappings
[i
].key_min
||
80 *key_size
> mappings
[i
].key_max
)
84 return mappings
[i
].name
;
91 * Do the actual en/decryption in an EVP context
93 static void crypt(private_openssl_crypter_t
*this, chunk_t data
, chunk_t iv
,
94 chunk_t
*dst
, int enc
)
102 *dst
= chunk_alloc(data
.len
);
106 EVP_CIPHER_CTX_init(&ctx
);
107 EVP_CipherInit_ex(&ctx
, this->cipher
, NULL
, NULL
, NULL
, enc
);
108 EVP_CIPHER_CTX_set_padding(&ctx
, 0); /* disable padding */
109 EVP_CIPHER_CTX_set_key_length(&ctx
, this->key
.len
);
110 EVP_CipherInit_ex(&ctx
, NULL
, NULL
, this->key
.ptr
, iv
.ptr
, enc
);
111 EVP_CipherUpdate(&ctx
, out
, &len
, data
.ptr
, data
.len
);
112 EVP_CipherFinal_ex(&ctx
, out
+ len
, &len
); /* since padding is disabled this does nothing */
113 EVP_CIPHER_CTX_cleanup(&ctx
);
116 METHOD(crypter_t
, decrypt
, void,
117 private_openssl_crypter_t
*this, chunk_t data
, chunk_t iv
, chunk_t
*dst
)
119 crypt(this, data
, iv
, dst
, 0);
122 METHOD(crypter_t
, encrypt
, void,
123 private_openssl_crypter_t
*this, chunk_t data
, chunk_t iv
, chunk_t
*dst
)
125 crypt(this, data
, iv
, dst
, 1);
128 METHOD(crypter_t
, get_block_size
, size_t,
129 private_openssl_crypter_t
*this)
131 return this->cipher
->block_size
;
134 METHOD(crypter_t
, get_iv_size
, size_t,
135 private_openssl_crypter_t
*this)
137 return this->cipher
->block_size
;
140 METHOD(crypter_t
, get_key_size
, size_t,
141 private_openssl_crypter_t
*this)
143 return this->key
.len
;
146 METHOD(crypter_t
, set_key
, void,
147 private_openssl_crypter_t
*this, chunk_t key
)
149 memcpy(this->key
.ptr
, key
.ptr
, min(key
.len
, this->key
.len
));
152 METHOD(crypter_t
, destroy
, void,
153 private_openssl_crypter_t
*this)
155 chunk_clear(&this->key
);
160 * Described in header
162 openssl_crypter_t
*openssl_crypter_create(encryption_algorithm_t algo
,
165 private_openssl_crypter_t
*this;
172 .get_block_size
= _get_block_size
,
173 .get_iv_size
= _get_iv_size
,
174 .get_key_size
= _get_key_size
,
184 this->cipher
= EVP_enc_null();
193 case 16: /* AES 128 */
194 this->cipher
= EVP_get_cipherbyname("aes128");
196 case 24: /* AES-192 */
197 this->cipher
= EVP_get_cipherbyname("aes192");
199 case 32: /* AES-256 */
200 this->cipher
= EVP_get_cipherbyname("aes256");
207 case ENCR_CAMELLIA_CBC
:
213 case 16: /* CAMELLIA 128 */
214 this->cipher
= EVP_get_cipherbyname("camellia128");
216 case 24: /* CAMELLIA 192 */
217 this->cipher
= EVP_get_cipherbyname("camellia192");
219 case 32: /* CAMELLIA 256 */
220 this->cipher
= EVP_get_cipherbyname("camellia256");
229 this->cipher
= EVP_des_ecb();
235 name
= lookup_algorithm(algo
, &key_size
);
238 /* algo unavailable or key_size invalid */
242 this->cipher
= EVP_get_cipherbyname(name
);
249 /* OpenSSL does not support the requested algo */
254 this->key
= chunk_alloc(key_size
);
256 return &this->public;