Removed len argument from proposal_get_token()
[strongswan.git] / src / libstrongswan / crypto / aead.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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 "aead.h"
17
18 #include <debug.h>
19
20 typedef struct private_aead_t private_aead_t;
21
22 /**
23 * Private data of an aead_t object.
24 */
25 struct private_aead_t {
26
27 /**
28 * Public aead_t interface.
29 */
30 aead_t public;
31
32 /**
33 * traditional crypter
34 */
35 crypter_t *crypter;
36
37 /**
38 * draditional signer
39 */
40 signer_t *signer;
41 };
42
43 METHOD(aead_t, encrypt, bool,
44 private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
45 chunk_t *encrypted)
46 {
47 chunk_t encr, sig;
48
49 if (!this->signer->get_signature(this->signer, assoc, NULL) ||
50 !this->signer->get_signature(this->signer, iv, NULL))
51 {
52 return FALSE;
53 }
54
55 if (encrypted)
56 {
57 if (!this->crypter->encrypt(this->crypter, plain, iv, &encr))
58 {
59 return FALSE;
60 }
61 if (!this->signer->allocate_signature(this->signer, encr, &sig))
62 {
63 free(encr.ptr);
64 return FALSE;
65 }
66 *encrypted = chunk_cat("cmm", iv, encr, sig);
67 }
68 else
69 {
70 if (!this->crypter->encrypt(this->crypter, plain, iv, NULL) ||
71 !this->signer->get_signature(this->signer,
72 plain, plain.ptr + plain.len))
73 {
74 return FALSE;
75 }
76 }
77 return TRUE;
78 }
79
80 METHOD(aead_t, decrypt, bool,
81 private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
82 chunk_t *plain)
83 {
84 chunk_t sig;
85 size_t bs;
86
87 bs = this->crypter->get_block_size(this->crypter);
88 sig.len = this->signer->get_block_size(this->signer);
89 if (sig.len > encrypted.len || (encrypted.len - sig.len) % bs)
90 {
91 DBG1(DBG_LIB, "invalid encrypted data length %d with block size %d",
92 encrypted.len - sig.len, bs);
93 return FALSE;
94 }
95 chunk_split(encrypted, "mm", encrypted.len - sig.len,
96 &encrypted, sig.len, &sig);
97
98 if (!this->signer->get_signature(this->signer, assoc, NULL) ||
99 !this->signer->get_signature(this->signer, iv, NULL))
100 {
101 return FALSE;
102 }
103 if (!this->signer->verify_signature(this->signer, encrypted, sig))
104 {
105 DBG1(DBG_LIB, "MAC verification failed");
106 return FALSE;
107 }
108 return this->crypter->decrypt(this->crypter, encrypted, iv, plain);
109 }
110
111 METHOD(aead_t, get_block_size, size_t,
112 private_aead_t *this)
113 {
114 return this->crypter->get_block_size(this->crypter);
115 }
116
117 METHOD(aead_t, get_icv_size, size_t,
118 private_aead_t *this)
119 {
120 return this->signer->get_block_size(this->signer);
121 }
122
123 METHOD(aead_t, get_iv_size, size_t,
124 private_aead_t *this)
125 {
126 return this->crypter->get_iv_size(this->crypter);
127 }
128
129 METHOD(aead_t, get_key_size, size_t,
130 private_aead_t *this)
131 {
132 return this->crypter->get_key_size(this->crypter) +
133 this->signer->get_key_size(this->signer);
134 }
135
136 METHOD(aead_t, set_key, bool,
137 private_aead_t *this, chunk_t key)
138 {
139 chunk_t sig, enc;
140
141 chunk_split(key, "mm", this->signer->get_key_size(this->signer), &sig,
142 this->crypter->get_key_size(this->crypter), &enc);
143
144 return this->signer->set_key(this->signer, sig) &&
145 this->crypter->set_key(this->crypter, enc);
146 }
147
148 METHOD(aead_t, destroy, void,
149 private_aead_t *this)
150 {
151 this->crypter->destroy(this->crypter);
152 this->signer->destroy(this->signer);
153 free(this);
154 }
155
156 /**
157 * See header
158 */
159 aead_t *aead_create(crypter_t *crypter, signer_t *signer)
160 {
161 private_aead_t *this;
162
163 INIT(this,
164 .public = {
165 .encrypt = _encrypt,
166 .decrypt = _decrypt,
167 .get_block_size = _get_block_size,
168 .get_icv_size = _get_icv_size,
169 .get_iv_size = _get_iv_size,
170 .get_key_size = _get_key_size,
171 .set_key = _set_key,
172 .destroy = _destroy,
173 },
174 .crypter = crypter,
175 .signer = signer,
176 );
177
178 return &this->public;
179 }