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
18 #include "openssl_crypter.h"
20 #include <openssl/evp.h>
22 typedef struct private_openssl_crypter_t private_openssl_crypter_t
;
25 * Private data of openssl_crypter_t
27 struct private_openssl_crypter_t
{
30 * Public part of this class.
32 openssl_crypter_t
public;
42 const EVP_CIPHER
*cipher
;
46 * Mapping from the algorithms defined in IKEv2 to
47 * OpenSSL algorithm names and their key length
51 * Identifier specified in IKEv2
56 * Name of the algorithm, as used in OpenSSL
61 * Minimum valid key length in bytes
66 * Maximum valid key length in bytes
69 } openssl_algorithm_t
;
71 #define END_OF_LIST -1
74 * Algorithms for encryption
76 static openssl_algorithm_t encryption_algs
[] = {
77 /* {ENCR_DES_IV64, "***", 0, 0}, */
78 {ENCR_DES
, "des", 8, 8}, /* 64 bits */
79 {ENCR_3DES
, "des3", 24, 24}, /* 192 bits */
80 {ENCR_RC5
, "rc5", 5, 255}, /* 40 to 2040 bits, RFC 2451 */
81 {ENCR_IDEA
, "idea", 16, 16}, /* 128 bits, RFC 2451 */
82 {ENCR_CAST
, "cast", 5, 16}, /* 40 to 128 bits, RFC 2451 */
83 {ENCR_BLOWFISH
, "blowfish", 5, 56}, /* 40 to 448 bits, RFC 2451 */
84 /* {ENCR_3IDEA, "***", 0, 0}, */
85 /* {ENCR_DES_IV32, "***", 0, 0}, */
86 /* {ENCR_NULL, "***", 0, 0}, */ /* handled separately */
87 /* {ENCR_AES_CBC, "***", 0, 0}, */ /* handled separately */
88 /* {ENCR_AES_CTR, "***", 0, 0}, */ /* disabled in evp.h */
89 {END_OF_LIST
, NULL
, 0, 0},
93 * Look up an OpenSSL algorithm name and validate its key size
95 static char* lookup_algorithm(openssl_algorithm_t
*openssl_algo
,
96 u_int16_t ikev2_algo
, size_t key_size
)
98 while (openssl_algo
->ikev2_id
!= END_OF_LIST
)
100 if (ikev2_algo
== openssl_algo
->ikev2_id
)
102 /* validate key size */
103 if (key_size
< openssl_algo
->key_size_min
||
104 key_size
> openssl_algo
->key_size_max
)
108 return openssl_algo
->name
;
115 static void crypt(private_openssl_crypter_t
*this, chunk_t data
,
116 chunk_t iv
, chunk_t
*dst
, int enc
)
124 *dst
= chunk_alloc(data
.len
);
128 EVP_CIPHER_CTX_init(&ctx
);
129 EVP_CipherInit_ex(&ctx
, this->cipher
, NULL
, this->key
.ptr
, iv
.ptr
, enc
);
130 EVP_CIPHER_CTX_set_padding(&ctx
, 0); /* disable padding */
131 EVP_CipherUpdate(&ctx
, out
, &len
, data
.ptr
, data
.len
);
132 EVP_CipherFinal_ex(&ctx
, out
, &len
); /* since padding is disabled this does nothing */
133 EVP_CIPHER_CTX_cleanup(&ctx
);
137 * Implementation of crypter_t.decrypt.
139 static void decrypt(private_openssl_crypter_t
*this, chunk_t data
,
140 chunk_t iv
, chunk_t
*dst
)
142 crypt(this, data
, iv
, dst
, 0);
147 * Implementation of crypter_t.encrypt.
149 static void encrypt (private_openssl_crypter_t
*this, chunk_t data
,
150 chunk_t iv
, chunk_t
*dst
)
152 crypt(this, data
, iv
, dst
, 1);
156 * Implementation of crypter_t.get_block_size.
158 static size_t get_block_size(private_openssl_crypter_t
*this)
160 return this->cipher
->block_size
;
164 * Implementation of crypter_t.get_key_size.
166 static size_t get_key_size(private_openssl_crypter_t
*this)
168 return this->key
.len
;
172 * Implementation of crypter_t.set_key.
174 static void set_key(private_openssl_crypter_t
*this, chunk_t key
)
176 memcpy(this->key
.ptr
, key
.ptr
, min(key
.len
, this->key
.len
));
180 * Implementation of crypter_t.destroy.
182 static void destroy (private_openssl_crypter_t
*this)
189 * Described in header
191 openssl_crypter_t
*openssl_crypter_create(encryption_algorithm_t algo
,
194 private_openssl_crypter_t
*this;
196 this = malloc_thing(private_openssl_crypter_t
);
201 this->cipher
= EVP_enc_null();
206 case 16: /* AES 128 */
207 this->cipher
= EVP_get_cipherbyname("aes128");
209 case 24: /* AES-192 */
210 this->cipher
= EVP_get_cipherbyname("aes192");
212 case 32: /* AES-256 */
213 this->cipher
= EVP_get_cipherbyname("aes256");
222 char* name
= lookup_algorithm(encryption_algs
, algo
, key_size
);
225 /* algo unavailable or key_size invalid */
229 this->cipher
= EVP_get_cipherbyname(name
);
236 /* OpenSSL does not support the requested algo */
241 this->key
= chunk_alloc(key_size
);
243 this->public.crypter_interface
.encrypt
= (void (*) (crypter_t
*, chunk_t
,chunk_t
, chunk_t
*)) encrypt
;
244 this->public.crypter_interface
.decrypt
= (void (*) (crypter_t
*, chunk_t
, chunk_t
, chunk_t
*)) decrypt
;
245 this->public.crypter_interface
.get_block_size
= (size_t (*) (crypter_t
*)) get_block_size
;
246 this->public.crypter_interface
.get_key_size
= (size_t (*) (crypter_t
*)) get_key_size
;
247 this->public.crypter_interface
.set_key
= (void (*) (crypter_t
*,chunk_t
)) set_key
;
248 this->public.crypter_interface
.destroy
= (void (*) (crypter_t
*)) destroy
;
250 return &this->public;