tls: Separate TLS protection to abstracted AEAD modes
[strongswan.git] / src / libtls / tls_aead_null.c
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 typedef struct private_tls_aead_t private_tls_aead_t;
19
20 /**
21 * Private data of an tls_aead_t object.
22 */
23 struct private_tls_aead_t {
24
25 /**
26 * Public tls_aead_t interface.
27 */
28 tls_aead_t public;
29
30 /**
31 * traditional signer
32 */
33 signer_t *signer;
34 };
35
36 /**
37 * Associated header data to create signature over
38 */
39 typedef struct __attribute__((__packed__)) {
40 u_int64_t seq;
41 u_int8_t type;
42 u_int16_t version;
43 u_int16_t length;
44 } sigheader_t;
45
46 METHOD(tls_aead_t, encrypt, bool,
47 private_tls_aead_t *this, tls_version_t version,
48 tls_content_type_t type, u_int64_t seq, chunk_t *data)
49 {
50 chunk_t assoc, mac;
51 sigheader_t hdr;
52
53 hdr.type = type;
54 htoun64(&hdr.seq, seq);
55 htoun16(&hdr.version, version);
56 htoun16(&hdr.length, data->len);
57
58 assoc = chunk_from_thing(hdr);
59 if (!this->signer->get_signature(this->signer, assoc, NULL) ||
60 !this->signer->allocate_signature(this->signer, *data, &mac))
61 {
62 return FALSE;
63 }
64 *data = chunk_cat("mm", *data, mac);
65 return TRUE;
66 }
67
68 METHOD(tls_aead_t, decrypt, bool,
69 private_tls_aead_t *this, tls_version_t version,
70 tls_content_type_t type, u_int64_t seq, chunk_t *data)
71 {
72 chunk_t assoc, mac;
73 sigheader_t hdr;
74
75 mac.len = this->signer->get_block_size(this->signer);
76 if (data->len < mac.len)
77 {
78 return FALSE;
79 }
80 mac = chunk_skip(*data, data->len - mac.len);
81 data->len -= mac.len;
82
83 hdr.type = type;
84 htoun64(&hdr.seq, seq);
85 htoun16(&hdr.version, version);
86 htoun16(&hdr.length, data->len);
87
88 assoc = chunk_from_thing(hdr);
89 if (!this->signer->get_signature(this->signer, assoc, NULL) ||
90 !this->signer->verify_signature(this->signer, *data, mac))
91 {
92 return FALSE;
93 }
94 return TRUE;
95 }
96
97 METHOD(tls_aead_t, get_mac_key_size, size_t,
98 private_tls_aead_t *this)
99 {
100 return this->signer->get_key_size(this->signer);
101 }
102
103 METHOD(tls_aead_t, get_encr_key_size, size_t,
104 private_tls_aead_t *this)
105 {
106 return 0;
107 }
108
109 METHOD(tls_aead_t, get_iv_size, size_t,
110 private_tls_aead_t *this)
111 {
112 return 0;
113 }
114
115 METHOD(tls_aead_t, set_keys, bool,
116 private_tls_aead_t *this, chunk_t mac, chunk_t encr, chunk_t iv)
117 {
118 if (iv.len || encr.len)
119 {
120 return FALSE;
121 }
122 return this->signer->set_key(this->signer, mac);
123 }
124
125 METHOD(tls_aead_t, destroy, void,
126 private_tls_aead_t *this)
127 {
128 this->signer->destroy(this->signer);
129 free(this);
130 }
131
132 /**
133 * See header
134 */
135 tls_aead_t *tls_aead_create_null(integrity_algorithm_t alg)
136 {
137 private_tls_aead_t *this;
138
139 INIT(this,
140 .public = {
141 .encrypt = _encrypt,
142 .decrypt = _decrypt,
143 .get_iv_size = _get_iv_size,
144 .get_mac_key_size = _get_mac_key_size,
145 .get_encr_key_size = _get_encr_key_size,
146 .get_iv_size = _get_iv_size,
147 .set_keys = _set_keys,
148 .destroy = _destroy,
149 },
150 .signer = lib->crypto->create_signer(lib->crypto, alg),
151 );
152
153 if (!this->signer)
154 {
155 free(this);
156 return NULL;
157 }
158
159 return &this->public;
160 }