3c5d8daec7c486122c56402f8f2a3f6893ccc9ea
[strongswan.git] / src / libstrongswan / plugins / af_alg / af_alg_hasher.c
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_hasher.h"
17 #include "af_alg_ops.h"
18
19 typedef struct private_af_alg_hasher_t private_af_alg_hasher_t;
20
21 /**
22 * Private data of af_alg_hasher_t
23 */
24 struct private_af_alg_hasher_t {
25
26 /**
27 * Public part of this class.
28 */
29 af_alg_hasher_t public;
30
31 /**
32 * AF_ALG operations
33 */
34 af_alg_ops_t *ops;
35
36 /**
37 * Size of the hash
38 */
39 size_t size;
40 };
41
42 /**
43 * Algorithm database
44 */
45 static struct {
46 hash_algorithm_t id;
47 char *name;
48 size_t size;
49 } algs[] = {
50 {HASH_SHA1, "sha1", HASH_SIZE_SHA1 },
51 {HASH_MD5, "md5", HASH_SIZE_MD5 },
52 {HASH_SHA224, "sha224", HASH_SIZE_SHA224 },
53 {HASH_SHA256, "sha256", HASH_SIZE_SHA256 },
54 {HASH_SHA384, "sha384", HASH_SIZE_SHA384 },
55 {HASH_SHA512, "sha512", HASH_SIZE_SHA512 },
56 {HASH_MD4, "md4", HASH_SIZE_MD4 },
57 };
58
59 /**
60 * See header.
61 */
62 void af_alg_hasher_probe()
63 {
64 af_alg_ops_t *ops;
65 int i;
66
67 for (i = 0; i < countof(algs); i++)
68 {
69 ops = af_alg_ops_create("hash", algs[i].name);
70 if (ops)
71 {
72 ops->destroy(ops);
73 lib->crypto->add_hasher(lib->crypto, algs[i].id, "af_alg",
74 (hasher_constructor_t)af_alg_hasher_create);
75 }
76 }
77 }
78
79 /**
80 * Get the kernel algorithm string and hash size for our identifier
81 */
82 static size_t lookup_alg(hash_algorithm_t algo, char **name)
83 {
84 int i;
85
86 for (i = 0; i < countof(algs); i++)
87 {
88 if (algs[i].id == algo)
89 {
90 *name = algs[i].name;
91 return algs[i].size;
92 }
93 }
94 return 0;
95 }
96
97 METHOD(hasher_t, get_hash_size, size_t,
98 private_af_alg_hasher_t *this)
99 {
100 return this->size;
101 }
102
103 METHOD(hasher_t, reset, void,
104 private_af_alg_hasher_t *this)
105 {
106 this->ops->reset(this->ops);
107 }
108
109 METHOD(hasher_t, get_hash, void,
110 private_af_alg_hasher_t *this, chunk_t chunk, u_int8_t *hash)
111 {
112 this->ops->hash(this->ops, chunk, hash, this->size);
113 }
114
115 METHOD(hasher_t, allocate_hash, void,
116 private_af_alg_hasher_t *this, chunk_t chunk, chunk_t *hash)
117 {
118 if (hash)
119 {
120 *hash = chunk_alloc(get_hash_size(this));
121 get_hash(this, chunk, hash->ptr);
122 }
123 else
124 {
125 get_hash(this, chunk, NULL);
126 }
127 }
128
129 METHOD(hasher_t, destroy, void,
130 private_af_alg_hasher_t *this)
131 {
132 this->ops->destroy(this->ops);
133 free(this);
134 }
135
136 /*
137 * Described in header
138 */
139 af_alg_hasher_t *af_alg_hasher_create(hash_algorithm_t algo)
140 {
141 private_af_alg_hasher_t *this;
142 char *name;
143 size_t size;
144
145 size = lookup_alg(algo, &name);
146 if (!size)
147 { /* not supported by kernel */
148 return NULL;
149 }
150
151 INIT(this,
152 .public = {
153 .hasher = {
154 .get_hash = _get_hash,
155 .allocate_hash = _allocate_hash,
156 .get_hash_size = _get_hash_size,
157 .reset = _reset,
158 .destroy = _destroy,
159 },
160 },
161 .ops = af_alg_ops_create("hash", name),
162 .size = size,
163 );
164 if (!this->ops)
165 {
166 free(this);
167 return NULL;
168 }
169 return &this->public;
170 }