]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/plugins/af_alg/af_alg_signer.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libstrongswan / plugins / af_alg / af_alg_signer.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "af_alg_signer.h"
18 #include "af_alg_ops.h"
19
20 typedef struct private_af_alg_signer_t private_af_alg_signer_t;
21
22 /**
23 * Private data structure with signing context.
24 */
25 struct private_af_alg_signer_t {
26
27 /**
28 * Public interface of af_alg_signer_t.
29 */
30 af_alg_signer_t public;
31
32 /**
33 * AF_ALG operations
34 */
35 af_alg_ops_t *ops;
36
37 /**
38 * Size of the truncated signature
39 */
40 size_t block_size;
41
42 /**
43 * Default key size
44 */
45 size_t key_size;
46 };
47
48 /**
49 * Algorithm database
50 */
51 static struct {
52 integrity_algorithm_t id;
53 char *name;
54 size_t block_size;
55 size_t key_size;
56 } algs[AF_ALG_SIGNER] = {
57 {AUTH_HMAC_SHA1_96, "hmac(sha1)", 12, 20, },
58 {AUTH_HMAC_SHA1_128, "hmac(sha1)", 16, 20, },
59 {AUTH_HMAC_SHA1_160, "hmac(sha1)", 20, 20, },
60 {AUTH_HMAC_SHA2_256_96, "hmac(sha256)", 12, 32, },
61 {AUTH_HMAC_SHA2_256_128, "hmac(sha256)", 16, 32, },
62 {AUTH_HMAC_MD5_96, "hmac(md5)", 12, 16, },
63 {AUTH_HMAC_MD5_128, "hmac(md5)", 16, 16, },
64 {AUTH_HMAC_SHA2_256_256, "hmac(sha256)", 32, 32, },
65 {AUTH_HMAC_SHA2_384_192, "hmac(sha384)", 24, 48, },
66 {AUTH_HMAC_SHA2_384_384, "hmac(sha384)", 48, 48, },
67 {AUTH_HMAC_SHA2_512_256, "hmac(sha512)", 32, 64, },
68 {AUTH_HMAC_SHA2_512_512, "hmac(sha512)", 64, 64, },
69 {AUTH_AES_XCBC_96, "xcbc(aes)", 12, 16, },
70 {AUTH_CAMELLIA_XCBC_96, "xcbc(camellia)", 12, 16, },
71 };
72
73 /**
74 * See header.
75 */
76 void af_alg_signer_probe(plugin_feature_t *features, int *pos)
77 {
78 af_alg_ops_t *ops;
79 int i;
80
81 for (i = 0; i < countof(algs); i++)
82 {
83 ops = af_alg_ops_create("hash", algs[i].name);
84 if (ops)
85 {
86 ops->destroy(ops);
87 features[(*pos)++] = PLUGIN_PROVIDE(SIGNER, algs[i].id);
88 }
89 }
90 }
91
92 /**
93 * Get the kernel algorithm string and block/key size for our identifier
94 */
95 static size_t lookup_alg(integrity_algorithm_t algo, char **name,
96 size_t *key_size)
97 {
98 int i;
99
100 for (i = 0; i < countof(algs); i++)
101 {
102 if (algs[i].id == algo)
103 {
104 *name = algs[i].name;
105 *key_size = algs[i].key_size;
106 return algs[i].block_size;
107 }
108 }
109 return 0;
110 }
111
112 METHOD(signer_t, get_signature, bool,
113 private_af_alg_signer_t *this, chunk_t data, uint8_t *buffer)
114 {
115 return this->ops->hash(this->ops, data, buffer, this->block_size);
116 }
117
118 METHOD(signer_t, allocate_signature, bool,
119 private_af_alg_signer_t *this, chunk_t data, chunk_t *chunk)
120 {
121 if (chunk)
122 {
123 *chunk = chunk_alloc(this->block_size);
124 return get_signature(this, data, chunk->ptr);
125 }
126 return get_signature(this, data, NULL);
127 }
128
129 METHOD(signer_t, verify_signature, bool,
130 private_af_alg_signer_t *this, chunk_t data, chunk_t signature)
131 {
132 char sig[this->block_size];
133
134 if (signature.len != this->block_size)
135 {
136 return FALSE;
137 }
138 if (!get_signature(this, data, sig))
139 {
140 return FALSE;
141 }
142 return memeq_const(signature.ptr, sig, signature.len);
143 }
144
145 METHOD(signer_t, get_key_size, size_t,
146 private_af_alg_signer_t *this)
147 {
148 return this->key_size;
149 }
150
151 METHOD(signer_t, get_block_size, size_t,
152 private_af_alg_signer_t *this)
153 {
154 return this->block_size;
155 }
156
157 METHOD(signer_t, set_key, bool,
158 private_af_alg_signer_t *this, chunk_t key)
159 {
160 this->ops->reset(this->ops);
161 return this->ops->set_key(this->ops, key);
162 }
163
164 METHOD(signer_t, destroy, void,
165 private_af_alg_signer_t *this)
166 {
167 this->ops->destroy(this->ops);
168 free(this);
169 }
170
171 /*
172 * Described in header
173 */
174 af_alg_signer_t *af_alg_signer_create(integrity_algorithm_t algo)
175 {
176 private_af_alg_signer_t *this;
177 size_t block_size, key_size;
178 char *name;
179
180 block_size = lookup_alg(algo, &name, &key_size);
181 if (!block_size)
182 { /* not supported by kernel */
183 return NULL;
184 }
185
186 INIT(this,
187 .public = {
188 .signer = {
189 .get_signature = _get_signature,
190 .allocate_signature = _allocate_signature,
191 .verify_signature = _verify_signature,
192 .get_key_size = _get_key_size,
193 .get_block_size = _get_block_size,
194 .set_key = _set_key,
195 .destroy = _destroy,
196 },
197 },
198 .ops = af_alg_ops_create("hash", name),
199 .block_size = block_size,
200 .key_size = key_size,
201 );
202 if (!this->ops)
203 {
204 free(this);
205 return NULL;
206 }
207 return &this->public;
208 }