Return to af_alg_signer.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / af_alg |
1.1 misho 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 "af_alg_signer.h"
17: #include "af_alg_ops.h"
18:
19: typedef struct private_af_alg_signer_t private_af_alg_signer_t;
20:
21: /**
22: * Private data structure with signing context.
23: */
24: struct private_af_alg_signer_t {
25:
26: /**
27: * Public interface of af_alg_signer_t.
28: */
29: af_alg_signer_t public;
30:
31: /**
32: * AF_ALG operations
33: */
34: af_alg_ops_t *ops;
35:
36: /**
37: * Size of the truncated signature
38: */
39: size_t block_size;
40:
41: /**
42: * Default key size
43: */
44: size_t key_size;
45: };
46:
47: /**
48: * Algorithm database
49: */
50: static struct {
51: integrity_algorithm_t id;
52: char *name;
53: size_t block_size;
54: size_t key_size;
55: } algs[AF_ALG_SIGNER] = {
56: {AUTH_HMAC_SHA1_96, "hmac(sha1)", 12, 20, },
57: {AUTH_HMAC_SHA1_128, "hmac(sha1)", 16, 20, },
58: {AUTH_HMAC_SHA1_160, "hmac(sha1)", 20, 20, },
59: {AUTH_HMAC_SHA2_256_96, "hmac(sha256)", 12, 32, },
60: {AUTH_HMAC_SHA2_256_128, "hmac(sha256)", 16, 32, },
61: {AUTH_HMAC_MD5_96, "hmac(md5)", 12, 16, },
62: {AUTH_HMAC_MD5_128, "hmac(md5)", 16, 16, },
1.1.1.2 ! misho 63: {AUTH_HMAC_SHA2_256_256, "hmac(sha256)", 32, 32, },
1.1 misho 64: {AUTH_HMAC_SHA2_384_192, "hmac(sha384)", 24, 48, },
65: {AUTH_HMAC_SHA2_384_384, "hmac(sha384)", 48, 48, },
66: {AUTH_HMAC_SHA2_512_256, "hmac(sha512)", 32, 64, },
67: {AUTH_HMAC_SHA2_512_512, "hmac(sha512)", 64, 64, },
68: {AUTH_AES_XCBC_96, "xcbc(aes)", 12, 16, },
69: {AUTH_CAMELLIA_XCBC_96, "xcbc(camellia)", 12, 16, },
70: };
71:
72: /**
73: * See header.
74: */
75: void af_alg_signer_probe(plugin_feature_t *features, int *pos)
76: {
77: af_alg_ops_t *ops;
78: int i;
79:
80: for (i = 0; i < countof(algs); i++)
81: {
82: ops = af_alg_ops_create("hash", algs[i].name);
83: if (ops)
84: {
85: ops->destroy(ops);
86: features[(*pos)++] = PLUGIN_PROVIDE(SIGNER, algs[i].id);
87: }
88: }
89: }
90:
91: /**
92: * Get the kernel algorithm string and block/key size for our identifier
93: */
94: static size_t lookup_alg(integrity_algorithm_t algo, char **name,
95: size_t *key_size)
96: {
97: int i;
98:
99: for (i = 0; i < countof(algs); i++)
100: {
101: if (algs[i].id == algo)
102: {
103: *name = algs[i].name;
104: *key_size = algs[i].key_size;
105: return algs[i].block_size;
106: }
107: }
108: return 0;
109: }
110:
111: METHOD(signer_t, get_signature, bool,
112: private_af_alg_signer_t *this, chunk_t data, uint8_t *buffer)
113: {
114: return this->ops->hash(this->ops, data, buffer, this->block_size);
115: }
116:
117: METHOD(signer_t, allocate_signature, bool,
118: private_af_alg_signer_t *this, chunk_t data, chunk_t *chunk)
119: {
120: if (chunk)
121: {
122: *chunk = chunk_alloc(this->block_size);
123: return get_signature(this, data, chunk->ptr);
124: }
125: return get_signature(this, data, NULL);
126: }
127:
128: METHOD(signer_t, verify_signature, bool,
129: private_af_alg_signer_t *this, chunk_t data, chunk_t signature)
130: {
131: char sig[this->block_size];
132:
133: if (signature.len != this->block_size)
134: {
135: return FALSE;
136: }
137: if (!get_signature(this, data, sig))
138: {
139: return FALSE;
140: }
141: return memeq_const(signature.ptr, sig, signature.len);
142: }
143:
144: METHOD(signer_t, get_key_size, size_t,
145: private_af_alg_signer_t *this)
146: {
147: return this->key_size;
148: }
149:
150: METHOD(signer_t, get_block_size, size_t,
151: private_af_alg_signer_t *this)
152: {
153: return this->block_size;
154: }
155:
156: METHOD(signer_t, set_key, bool,
157: private_af_alg_signer_t *this, chunk_t key)
158: {
159: this->ops->reset(this->ops);
160: return this->ops->set_key(this->ops, key);
161: }
162:
163: METHOD(signer_t, destroy, void,
164: private_af_alg_signer_t *this)
165: {
166: this->ops->destroy(this->ops);
167: free(this);
168: }
169:
170: /*
171: * Described in header
172: */
173: af_alg_signer_t *af_alg_signer_create(integrity_algorithm_t algo)
174: {
175: private_af_alg_signer_t *this;
176: size_t block_size, key_size;
177: char *name;
178:
179: block_size = lookup_alg(algo, &name, &key_size);
180: if (!block_size)
181: { /* not supported by kernel */
182: return NULL;
183: }
184:
185: INIT(this,
186: .public = {
187: .signer = {
188: .get_signature = _get_signature,
189: .allocate_signature = _allocate_signature,
190: .verify_signature = _verify_signature,
191: .get_key_size = _get_key_size,
192: .get_block_size = _get_block_size,
193: .set_key = _set_key,
194: .destroy = _destroy,
195: },
196: },
197: .ops = af_alg_ops_create("hash", name),
198: .block_size = block_size,
199: .key_size = key_size,
200: );
201: if (!this->ops)
202: {
203: free(this);
204: return NULL;
205: }
206: return &this->public;
207: }