Annotation of embedaddon/strongswan/src/libtls/tls_aead.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2014 Martin Willi
3: * Copyright (C) 2014 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 "tls_aead.h"
17:
18: #include <crypto/iv/iv_gen_rand.h>
19:
20: typedef struct private_tls_aead_t private_tls_aead_t;
21:
22: /**
23: * Private data of an tls_aead_t object.
24: */
25: struct private_tls_aead_t {
26:
27: /**
28: * Public tls_aead_t interface.
29: */
30: tls_aead_t public;
31:
32: /**
33: * AEAD transform
34: */
35: aead_t *aead;
36:
37: /**
38: * Size of salt, the implicit nonce
39: */
40: size_t salt;
41: };
42:
43: /**
44: * Associated header data to create signature over
45: */
46: typedef struct __attribute__((__packed__)) {
47: uint64_t seq;
48: uint8_t type;
49: uint16_t version;
50: uint16_t length;
51: } sigheader_t;
52:
53: METHOD(tls_aead_t, encrypt, bool,
54: private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
55: uint64_t seq, chunk_t *data)
56: {
57: chunk_t assoc, encrypted, iv, plain;
58: uint8_t icvlen;
59: sigheader_t hdr;
60: iv_gen_t *gen;
61:
62: gen = this->aead->get_iv_gen(this->aead);
63: iv.len = this->aead->get_iv_size(this->aead);
64: icvlen = this->aead->get_icv_size(this->aead);
65:
66: encrypted = chunk_alloc(iv.len + data->len + icvlen);
67: iv.ptr = encrypted.ptr;
68: if (!gen->get_iv(gen, seq, iv.len, iv.ptr))
69: {
70: chunk_free(&encrypted);
71: return FALSE;
72: }
73: memcpy(encrypted.ptr + iv.len, data->ptr, data->len);
74: plain = chunk_skip(encrypted, iv.len);
75: plain.len -= icvlen;
76:
77: hdr.type = type;
78: htoun64(&hdr.seq, seq);
79: htoun16(&hdr.version, version);
80: htoun16(&hdr.length, plain.len);
81:
82: assoc = chunk_from_thing(hdr);
83: if (!this->aead->encrypt(this->aead, plain, assoc, iv, NULL))
84: {
85: chunk_free(&encrypted);
86: return FALSE;
87: }
88: chunk_free(data);
89: *data = encrypted;
90: return TRUE;
91: }
92:
93: METHOD(tls_aead_t, decrypt, bool,
94: private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
95: uint64_t seq, chunk_t *data)
96: {
97: chunk_t assoc, iv;
98: uint8_t icvlen;
99: sigheader_t hdr;
100:
101: iv.len = this->aead->get_iv_size(this->aead);
102: if (data->len < iv.len)
103: {
104: return FALSE;
105: }
106: iv.ptr = data->ptr;
107: *data = chunk_skip(*data, iv.len);
108: icvlen = this->aead->get_icv_size(this->aead);
109: if (data->len < icvlen)
110: {
111: return FALSE;
112: }
113:
114: hdr.type = type;
115: htoun64(&hdr.seq, seq);
116: htoun16(&hdr.version, version);
117: htoun16(&hdr.length, data->len - icvlen);
118:
119: assoc = chunk_from_thing(hdr);
120: if (!this->aead->decrypt(this->aead, *data, assoc, iv, NULL))
121: {
122: return FALSE;
123: }
124: data->len -= icvlen;
125: return TRUE;
126: }
127:
128: METHOD(tls_aead_t, get_mac_key_size, size_t,
129: private_tls_aead_t *this)
130: {
131: return 0;
132: }
133:
134: METHOD(tls_aead_t, get_encr_key_size, size_t,
135: private_tls_aead_t *this)
136: {
137: return this->aead->get_key_size(this->aead) - this->salt;
138: }
139:
140: METHOD(tls_aead_t, get_iv_size, size_t,
141: private_tls_aead_t *this)
142: {
143: return this->salt;
144: }
145:
146: METHOD(tls_aead_t, set_keys, bool,
147: private_tls_aead_t *this, chunk_t mac, chunk_t encr, chunk_t iv)
148: {
149: chunk_t key;
150:
151: if (mac.len)
152: {
153: return FALSE;
154: }
155: key = chunk_cata("cc", encr, iv);
156: return this->aead->set_key(this->aead, key);
157: }
158:
159: METHOD(tls_aead_t, destroy, void,
160: private_tls_aead_t *this)
161: {
162: this->aead->destroy(this->aead);
163: free(this);
164: }
165:
166: /**
167: * See header
168: */
169: tls_aead_t *tls_aead_create_aead(encryption_algorithm_t encr, size_t encr_size)
170: {
171: private_tls_aead_t *this;
172: size_t salt;
173:
174: switch (encr)
175: {
176: case ENCR_AES_GCM_ICV8:
177: case ENCR_AES_GCM_ICV12:
178: case ENCR_AES_GCM_ICV16:
179: case ENCR_AES_CCM_ICV8:
180: case ENCR_AES_CCM_ICV12:
181: case ENCR_AES_CCM_ICV16:
182: case ENCR_CAMELLIA_CCM_ICV8:
183: case ENCR_CAMELLIA_CCM_ICV12:
184: case ENCR_CAMELLIA_CCM_ICV16:
185: salt = 4;
186: break;
187: default:
188: return NULL;
189: }
190:
191: INIT(this,
192: .public = {
193: .encrypt = _encrypt,
194: .decrypt = _decrypt,
195: .get_mac_key_size = _get_mac_key_size,
196: .get_encr_key_size = _get_encr_key_size,
197: .get_iv_size = _get_iv_size,
198: .set_keys = _set_keys,
199: .destroy = _destroy,
200: },
201: .aead = lib->crypto->create_aead(lib->crypto, encr, encr_size, salt),
202: .salt = salt,
203: );
204:
205: if (!this->aead)
206: {
207: free(this);
208: return NULL;
209: }
210:
211: if (this->aead->get_block_size(this->aead) != 1)
212: { /* TLS does not define any padding scheme for AEAD */
213: destroy(this);
214: return NULL;
215: }
216:
217: return &this->public;
218: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>