Annotation of embedaddon/strongswan/src/libstrongswan/plugins/af_alg/af_alg_crypter.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2010 Martin Willi
3: * Copyright (C) 2010 revosec AG
4: *
5: * Copyright (C) 2019 Andreas Steffen
6: * HSR Hochschule fuer Technik Rapperswil
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program is distributed in the hope that it will be useful, but
14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16: * for more details.
17: */
18:
19: #include "af_alg_crypter.h"
20: #include "af_alg_ops.h"
21:
22: typedef struct private_af_alg_crypter_t private_af_alg_crypter_t;
23:
24: /**
25: * Private data of af_alg_crypter_t
26: */
27: struct private_af_alg_crypter_t {
28:
29: /**
30: * Public part of this class.
31: */
32: af_alg_crypter_t public;
33:
34: /**
35: * AF_ALG operations
36: */
37: af_alg_ops_t *ops;
38:
39: /**
40: * Size of the truncated signature
41: */
42: size_t block_size;
43:
44: /**
45: * Size of the keymat
46: */
47: size_t keymat_size;
48:
49: /**
50: * Size of initialization vector
51: */
52: size_t iv_size;
53: };
54:
55: /**
56: * Algorithm database
57: */
58: static struct {
59: encryption_algorithm_t id;
60: char *name;
61: size_t block_size;
62: /* key size of the algorithm */
63: size_t key_size;
64: /* size of the keying material (key + nonce for ctr mode) */
65: size_t keymat_size;
66: size_t iv_size;
67: } algs[AF_ALG_CRYPTER] = {
68: {ENCR_DES, "cbc(des)", 8, 8, 8, 8, },
69: {ENCR_DES_ECB, "ecb(des)", 8, 8, 8, 0, },
70: {ENCR_3DES, "cbc(des3_ede)", 8, 24, 24, 8, },
71: {ENCR_AES_CBC, "cbc(aes)", 16, 16, 16, 16, },
72: {ENCR_AES_CBC, "cbc(aes)", 16, 24, 24, 16, },
73: {ENCR_AES_CBC, "cbc(aes)", 16, 32, 32, 16, },
74: {ENCR_AES_ECB, "ecb(aes)", 16, 16, 16, 0, },
75: {ENCR_AES_ECB, "ecb(aes)", 16, 24, 24, 0, },
76: {ENCR_AES_ECB, "ecb(aes)", 16, 32, 32, 0, },
77: {ENCR_AES_CTR, "rfc3686(ctr(aes))", 1, 16, 20, 8, },
78: {ENCR_AES_CTR, "rfc3686(ctr(aes))", 1, 24, 28, 8, },
79: {ENCR_AES_CTR, "rfc3686(ctr(aes))", 1, 32, 36, 8, },
80: {ENCR_CAMELLIA_CBC, "cbc(camellia)", 16, 16, 16, 16, },
81: {ENCR_CAMELLIA_CBC, "cbc(camellia)", 16, 24, 24, 16, },
82: {ENCR_CAMELLIA_CBC, "cbc(camellia)", 16, 32, 32, 16, },
83: {ENCR_CAMELLIA_CTR, "rfc3686(ctr(camellia))", 1, 16, 20, 8, },
84: {ENCR_CAMELLIA_CTR, "rfc3686(ctr(camellia))", 1, 24, 28, 8, },
85: {ENCR_CAMELLIA_CTR, "rfc3686(ctr(camellia))", 1, 32, 36, 8, },
86: {ENCR_CAST, "cbc(cast5)", 8, 16, 16, 8, },
87: {ENCR_BLOWFISH, "cbc(blowfish)", 8, 16, 16, 8, },
88: {ENCR_BLOWFISH, "cbc(blowfish)", 8, 24, 24, 8, },
89: {ENCR_BLOWFISH, "cbc(blowfish)", 8, 32, 32, 8, },
90: {ENCR_SERPENT_CBC, "cbc(serpent)", 16, 16, 16, 16, },
91: {ENCR_SERPENT_CBC, "cbc(serpent)", 16, 24, 24, 16, },
92: {ENCR_SERPENT_CBC, "cbc(serpent)", 16, 32, 32, 16, },
93: {ENCR_TWOFISH_CBC, "cbc(twofish)", 16, 16, 16, 16, },
94: {ENCR_TWOFISH_CBC, "cbc(twofish)", 16, 24, 24, 16, },
95: {ENCR_TWOFISH_CBC, "cbc(twofish)", 16, 32, 32, 16, },
96: };
97:
98: /**
99: * See header.
100: */
101: void af_alg_crypter_probe(plugin_feature_t *features, int *pos)
102: {
103: af_alg_ops_t *ops;
104: int i;
105:
106: for (i = 0; i < countof(algs); i++)
107: {
108: ops = af_alg_ops_create("skcipher", algs[i].name);
109: if (ops)
110: {
111: ops->destroy(ops);
112: features[(*pos)++] = PLUGIN_PROVIDE(CRYPTER,
113: algs[i].id, algs[i].key_size);
114: }
115: }
116: }
117:
118: /**
119: * Get the kernel algorithm string and block/key size for our identifier
120: */
121: static size_t lookup_alg(encryption_algorithm_t algo, char **name,
122: size_t key_size, size_t *keymat_size, size_t *iv_size)
123: {
124: int i;
125:
126: for (i = 0; i < countof(algs); i++)
127: {
128: if (algs[i].id == algo &&
129: (key_size == 0 || algs[i].key_size == key_size))
130: {
131: *name = algs[i].name;
132: *keymat_size = algs[i].keymat_size;
133: *iv_size = algs[i].iv_size;
134: return algs[i].block_size;
135: }
136: }
137: return 0;
138: }
139:
140: METHOD(crypter_t, decrypt, bool,
141: private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
142: {
143: if (dst)
144: {
145: *dst = chunk_alloc(data.len);
146: return this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, dst->ptr);
147: }
148: return this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, data.ptr);
149: }
150:
151: METHOD(crypter_t, encrypt, bool,
152: private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
153: {
154: if (dst)
155: {
156: *dst = chunk_alloc(data.len);
157: return this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, dst->ptr);
158: }
159: return this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, data.ptr);
160: }
161:
162: METHOD(crypter_t, get_block_size, size_t,
163: private_af_alg_crypter_t *this)
164: {
165: return this->block_size;
166: }
167:
168: METHOD(crypter_t, get_iv_size, size_t,
169: private_af_alg_crypter_t *this)
170: {
171: return this->iv_size;
172: }
173:
174: METHOD(crypter_t, get_key_size, size_t,
175: private_af_alg_crypter_t *this)
176: {
177: return this->keymat_size;
178: }
179:
180: METHOD(crypter_t, set_key, bool,
181: private_af_alg_crypter_t *this, chunk_t key)
182: {
183: return this->ops->set_key(this->ops, key);
184: }
185:
186: METHOD(crypter_t, destroy, void,
187: private_af_alg_crypter_t *this)
188: {
189: this->ops->destroy(this->ops);
190: free(this);
191: }
192:
193: /*
194: * Described in header
195: */
196: af_alg_crypter_t *af_alg_crypter_create(encryption_algorithm_t algo,
197: size_t key_size)
198: {
199: private_af_alg_crypter_t *this;
200: size_t block_size, keymat_size, iv_size;
201: char *name;
202:
203: block_size = lookup_alg(algo, &name, key_size, &keymat_size, &iv_size);
204: if (!block_size)
205: { /* not supported by kernel */
206: return NULL;
207: }
208:
209: INIT(this,
210: .public = {
211: .crypter = {
212: .encrypt = _encrypt,
213: .decrypt = _decrypt,
214: .get_block_size = _get_block_size,
215: .get_iv_size = _get_iv_size,
216: .get_key_size = _get_key_size,
217: .set_key = _set_key,
218: .destroy = _destroy,
219: },
220: },
221: .block_size = block_size,
222: .keymat_size = keymat_size,
223: .iv_size = iv_size,
224: .ops = af_alg_ops_create("skcipher", name),
225: );
226:
227: if (!this->ops)
228: {
229: free(this);
230: return NULL;
231: }
232: return &this->public;
233: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>