gcrypt RSA private key implementation
[strongswan.git] / src / libstrongswan / plugins / gcrypt / gcrypt_crypter.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
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>.
9 *
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
13 * for more details.
14 */
15
16 #include "gcrypt_crypter.h"
17
18 #include <gcrypt.h>
19
20 #include <debug.h>
21
22 typedef struct private_gcrypt_crypter_t private_gcrypt_crypter_t;
23
24 /**
25 * Private data of gcrypt_crypter_t
26 */
27 struct private_gcrypt_crypter_t {
28
29 /**
30 * Public part of this class.
31 */
32 gcrypt_crypter_t public;
33
34 /**
35 * gcrypt cipher handle
36 */
37 gcry_cipher_hd_t h;
38
39 /**
40 * gcrypt algorithm identifier
41 */
42 int alg;
43 };
44
45 /**
46 * Implementation of crypter_t.decrypt.
47 */
48 static void decrypt(private_gcrypt_crypter_t *this, chunk_t data,
49 chunk_t iv, chunk_t *dst)
50 {
51 gcry_cipher_setiv(this->h, iv.ptr, iv.len);
52
53 if (dst)
54 {
55 *dst = chunk_alloc(data.len);
56 gcry_cipher_decrypt(this->h, dst->ptr, dst->len, data.ptr, data.len);
57 }
58 else
59 {
60 gcry_cipher_decrypt(this->h, data.ptr, data.len, NULL, 0);
61 }
62 }
63
64 /**
65 * Implementation of crypter_t.encrypt.
66 */
67 static void encrypt(private_gcrypt_crypter_t *this, chunk_t data,
68 chunk_t iv, chunk_t *dst)
69 {
70 gcry_cipher_setiv(this->h, iv.ptr, iv.len);
71
72 if (dst)
73 {
74 *dst = chunk_alloc(data.len);
75 gcry_cipher_encrypt(this->h, dst->ptr, dst->len, data.ptr, data.len);
76 }
77 else
78 {
79 gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0);
80 }
81 }
82
83 /**
84 * Implementation of crypter_t.get_block_size.
85 */
86 static size_t get_block_size(private_gcrypt_crypter_t *this)
87 {
88 size_t len = 0;
89
90 gcry_cipher_algo_info(this->alg, GCRYCTL_GET_BLKLEN, NULL, &len);
91 return len;
92 }
93
94 /**
95 * Implementation of crypter_t.get_key_size.
96 */
97 static size_t get_key_size(private_gcrypt_crypter_t *this)
98 {
99 size_t len = 0;
100
101 gcry_cipher_algo_info(this->alg, GCRYCTL_GET_KEYLEN, NULL, &len);
102 return len;
103 }
104
105 /**
106 * Implementation of crypter_t.set_key.
107 */
108 static void set_key(private_gcrypt_crypter_t *this, chunk_t key)
109 {
110 gcry_cipher_setkey(this->h, key.ptr, key.len);
111 }
112
113 /**
114 * Implementation of crypter_t.destroy.
115 */
116 static void destroy (private_gcrypt_crypter_t *this)
117 {
118 gcry_cipher_close(this->h);
119 free(this);
120 }
121
122 /*
123 * Described in header
124 */
125 gcrypt_crypter_t *gcrypt_crypter_create(encryption_algorithm_t algo,
126 size_t key_size)
127 {
128 private_gcrypt_crypter_t *this;
129 int gcrypt_alg;
130 int mode = GCRY_CIPHER_MODE_CBC;
131 gcry_error_t err;
132
133 switch (algo)
134 {
135 case ENCR_DES:
136 gcrypt_alg = GCRY_CIPHER_DES;
137 break;
138 case ENCR_DES_ECB:
139 gcrypt_alg = GCRY_CIPHER_DES;
140 mode = GCRY_CIPHER_MODE_ECB;
141 break;
142 case ENCR_3DES:
143 gcrypt_alg = GCRY_CIPHER_3DES;
144 break;
145 case ENCR_IDEA:
146 gcrypt_alg = GCRY_CIPHER_IDEA;
147 break;
148 case ENCR_CAST:
149 gcrypt_alg = GCRY_CIPHER_CAST5;
150 break;
151 case ENCR_BLOWFISH:
152 gcrypt_alg = GCRY_CIPHER_BLOWFISH;
153 break;
154 /* case ENCR_AES_CTR:
155 mode = GCRY_CIPHER_MODE_CTR; */
156 /* fall */
157 case ENCR_AES_CBC:
158 switch (key_size)
159 {
160 case 16:
161 gcrypt_alg = GCRY_CIPHER_AES128;
162 break;
163 case 24:
164 gcrypt_alg = GCRY_CIPHER_AES192;
165 break;
166 case 32:
167 gcrypt_alg = GCRY_CIPHER_AES256;
168 break;
169 default:
170 return NULL;
171 }
172 break;
173 /* case ENCR_CAMELLIA_CTR:
174 mode = GCRY_CIPHER_MODE_CTR; */
175 /* fall */
176 case ENCR_CAMELLIA_CBC:
177 switch (key_size)
178 {
179 case 16:
180 gcrypt_alg = GCRY_CIPHER_CAMELLIA128;
181 break;
182 case 24:
183 gcrypt_alg = GCRY_CIPHER_CAMELLIA192;
184 break;
185 case 32:
186 gcrypt_alg = GCRY_CIPHER_CAMELLIA256;
187 break;
188 default:
189 return NULL;
190 }
191 break;
192 case ENCR_SERPENT_CBC:
193 switch (key_size)
194 {
195 case 16:
196 gcrypt_alg = GCRY_CIPHER_SERPENT128;
197 break;
198 case 24:
199 gcrypt_alg = GCRY_CIPHER_SERPENT192;
200 break;
201 case 32:
202 gcrypt_alg = GCRY_CIPHER_SERPENT256;
203 break;
204 default:
205 return NULL;
206 }
207 break;
208 case ENCR_TWOFISH_CBC:
209 switch (key_size)
210 {
211 case 16:
212 gcrypt_alg = GCRY_CIPHER_TWOFISH128;
213 break;
214 case 32:
215 gcrypt_alg = GCRY_CIPHER_TWOFISH;
216 break;
217 default:
218 return NULL;
219 }
220 break;
221 default:
222 return NULL;
223 }
224
225 this = malloc_thing(private_gcrypt_crypter_t);
226
227 this->alg = gcrypt_alg;
228 err = gcry_cipher_open(&this->h, gcrypt_alg, mode, 0);
229 if (err)
230 {
231 DBG1("grcy_cipher_open(%N) failed: %s",
232 encryption_algorithm_names, algo, gpg_strerror(err));
233 free(this);
234 return NULL;
235 }
236
237 this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *))encrypt;
238 this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *))decrypt;
239 this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *))get_block_size;
240 this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *))get_key_size;
241 this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t))set_key;
242 this->public.crypter_interface.destroy = (void (*) (crypter_t *))destroy;
243
244 return &this->public;
245 }
246