]> git.ipfire.org Git - people/ms/strongswan.git/blob - src/libstrongswan/plugins/botan/botan_crypter.c
3ec5c4d5e4182cf4cbefd738cc08b9a184c9c852
[people/ms/strongswan.git] / src / libstrongswan / plugins / botan / botan_crypter.c
1 /*
2 * Copyright (C) 2018 René Korthaus
3 * Copyright (C) 2018 Konstantinos Kolelis
4 * Copyright (C) 2018 Tobias Hommel
5 * Rohde & Schwarz Cybersecurity GmbH
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26 #include "botan_crypter.h"
27
28 #include <botan/build.h>
29
30 #if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC)
31
32 #include <botan/ffi.h>
33
34 typedef struct private_botan_crypter_t private_botan_crypter_t;
35
36 /**
37 * Private data of botan_crypter_t
38 */
39 struct private_botan_crypter_t {
40
41 /**
42 * Public part of this class
43 */
44 botan_crypter_t public;
45
46 /**
47 * The key
48 */
49 chunk_t key;
50
51 /**
52 * The cipher name
53 */
54 const char* cipher_name;
55 };
56
57 /**
58 * Do the actual en/decryption
59 */
60 static bool crypt(private_botan_crypter_t *this, chunk_t data, chunk_t iv,
61 chunk_t *dst, uint32_t init_flag)
62 {
63 botan_cipher_t cipher;
64 size_t output_written = 0;
65 size_t input_consumed = 0;
66 uint8_t *in, *out;
67 bool success = FALSE;
68
69 in = data.ptr;
70 if (dst)
71 {
72 *dst = chunk_alloc(data.len);
73 out = dst->ptr;
74 }
75 else
76 {
77 out = data.ptr;
78 }
79
80 if (botan_cipher_init(&cipher, this->cipher_name, init_flag))
81 {
82 return FALSE;
83 }
84
85 if (!botan_cipher_set_key(cipher, this->key.ptr, this->key.len) &&
86 !botan_cipher_start(cipher, iv.ptr, iv.len) &&
87 !botan_cipher_update(cipher, BOTAN_CIPHER_UPDATE_FLAG_FINAL, out,
88 data.len, &output_written, in, data.len,
89 &input_consumed) &&
90 (output_written == input_consumed))
91 {
92 success = TRUE;
93 }
94
95 botan_cipher_destroy(cipher);
96 return success;
97 }
98
99 METHOD(crypter_t, decrypt, bool,
100 private_botan_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
101 {
102 return crypt(this, data, iv, dst, BOTAN_CIPHER_INIT_FLAG_DECRYPT);
103 }
104
105
106 METHOD(crypter_t, encrypt, bool,
107 private_botan_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
108 {
109 return crypt(this, data, iv, dst, BOTAN_CIPHER_INIT_FLAG_ENCRYPT);
110 }
111
112 METHOD(crypter_t, get_block_size, size_t,
113 private_botan_crypter_t *this)
114 {
115 return AES_BLOCK_SIZE;
116 }
117
118 METHOD(crypter_t, get_iv_size, size_t,
119 private_botan_crypter_t *this)
120 {
121 return AES_BLOCK_SIZE;
122 }
123
124 METHOD(crypter_t, get_key_size, size_t,
125 private_botan_crypter_t *this)
126 {
127 return this->key.len;
128 }
129
130 METHOD(crypter_t, set_key, bool,
131 private_botan_crypter_t *this, chunk_t key)
132 {
133 memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len));
134 return TRUE;
135 }
136
137 METHOD(crypter_t, destroy, void,
138 private_botan_crypter_t *this)
139 {
140 chunk_clear(&this->key);
141 free(this);
142 }
143
144 /*
145 * Described in header
146 */
147 botan_crypter_t *botan_crypter_create(encryption_algorithm_t algo,
148 size_t key_size)
149 {
150 private_botan_crypter_t *this;
151
152 INIT(this,
153 .public = {
154 .crypter = {
155 .encrypt = _encrypt,
156 .decrypt = _decrypt,
157 .get_block_size = _get_block_size,
158 .get_iv_size = _get_iv_size,
159 .get_key_size = _get_key_size,
160 .set_key = _set_key,
161 .destroy = _destroy,
162 },
163 },
164 );
165
166 switch (algo)
167 {
168 case ENCR_AES_CBC:
169 switch (key_size)
170 {
171 case 16:
172 /* AES 128 */
173 this->cipher_name = "AES-128/CBC/NoPadding";
174 break;
175 case 24:
176 /* AES-192 */
177 this->cipher_name = "AES-192/CBC/NoPadding";
178 break;
179 case 32:
180 /* AES-256 */
181 this->cipher_name = "AES-256/CBC/NoPadding";
182 break;
183 default:
184 free(this);
185 return NULL;
186 }
187 break;
188 default:
189 free(this);
190 return NULL;
191 }
192
193 this->key = chunk_alloc(key_size);
194 return &this->public;
195 }
196
197 #endif