4422a6817f0e9c248438898aef01aefaeac90c36
[platform/upstream/cryptsetup.git] / lib / crypto_backend / crypto_nettle.c
1 /*
2  * Nettle crypto backend implementation
3  *
4  * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * version 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <nettle/sha.h>
24 #include <nettle/hmac.h>
25 #include "crypto_backend.h"
26
27 typedef void (*init_func) (void *);
28 typedef void (*update_func) (void *, unsigned, const uint8_t *);
29 typedef void (*digest_func) (void *, unsigned, uint8_t *);
30 typedef void (*set_key_func) (void *, unsigned, const uint8_t *);
31
32 struct hash_alg {
33         const char *name;
34         int length;
35         init_func init;
36         update_func update;
37         digest_func digest;
38         update_func hmac_update;
39         digest_func hmac_digest;
40         set_key_func hmac_set_key;
41 };
42
43 static struct hash_alg hash_algs[] = {
44         { "sha1", SHA1_DIGEST_SIZE,
45                 (init_func) sha1_init,
46                 (update_func) sha1_update,
47                 (digest_func) sha1_digest,
48                 (update_func) hmac_sha1_update,
49                 (digest_func) hmac_sha1_digest,
50                 (set_key_func) hmac_sha1_set_key,
51         },
52         { "sha224", SHA224_DIGEST_SIZE,
53                 (init_func) sha224_init,
54                 (update_func) sha224_update,
55                 (digest_func) sha224_digest,
56                 (update_func) hmac_sha224_update,
57                 (digest_func) hmac_sha224_digest,
58                 (set_key_func) hmac_sha224_set_key,
59         },
60         { "sha256", SHA256_DIGEST_SIZE,
61                 (init_func) sha256_init,
62                 (update_func) sha256_update,
63                 (digest_func) sha256_digest,
64                 (update_func) hmac_sha256_update,
65                 (digest_func) hmac_sha256_digest,
66                 (set_key_func) hmac_sha256_set_key,
67         },
68         { "sha384", SHA384_DIGEST_SIZE,
69                 (init_func) sha384_init,
70                 (update_func) sha384_update,
71                 (digest_func) sha384_digest,
72                 (update_func) hmac_sha384_update,
73                 (digest_func) hmac_sha384_digest,
74                 (set_key_func) hmac_sha384_set_key,
75         },
76         { "sha512", SHA512_DIGEST_SIZE,
77                 (init_func) sha512_init,
78                 (update_func) sha512_update,
79                 (digest_func) sha512_digest,
80                 (update_func) hmac_sha512_update,
81                 (digest_func) hmac_sha512_digest,
82                 (set_key_func) hmac_sha512_set_key,
83         },
84         { "ripemd160", RIPEMD160_DIGEST_SIZE,
85                 (init_func) ripemd160_init,
86                 (update_func) ripemd160_update,
87                 (digest_func) ripemd160_digest,
88                 (update_func) hmac_ripemd160_update,
89                 (digest_func) hmac_ripemd160_digest,
90                 (set_key_func) hmac_ripemd160_set_key,
91         },
92         { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, }
93 };
94
95 struct crypt_hash {
96         const struct hash_alg *hash;
97         union {
98                 struct sha1_ctx sha1;
99                 struct sha224_ctx sha224;
100                 struct sha256_ctx sha256;
101                 struct sha384_ctx sha384;
102                 struct sha512_ctx sha512;
103         } nettle_ctx;
104 };
105
106 struct crypt_hmac {
107         const struct hash_alg *hash;
108         union {
109                 struct hmac_sha1_ctx sha1;
110                 struct hmac_sha224_ctx sha224;
111                 struct hmac_sha256_ctx sha256;
112                 struct hmac_sha384_ctx sha384;
113                 struct hmac_sha512_ctx sha512;
114         } nettle_ctx;
115         size_t key_length;
116         uint8_t *key;
117 };
118
119 uint32_t crypt_backend_flags(void)
120 {
121         return 0;
122 }
123
124 static struct hash_alg *_get_alg(const char *name)
125 {
126         int i = 0;
127
128         while (name && hash_algs[i].name) {
129                 if (!strcmp(name, hash_algs[i].name))
130                         return &hash_algs[i];
131                 i++;
132         }
133         return NULL;
134 }
135
136 int crypt_backend_init(struct crypt_device *ctx)
137 {
138         log_dbg("Initialising Nettle crypto backend.");
139         return 0;
140 }
141
142 /* HASH */
143 int crypt_hash_size(const char *name)
144 {
145         struct hash_alg *ha = _get_alg(name);
146
147         return ha ? ha->length : -EINVAL;
148 }
149
150 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
151 {
152         struct crypt_hash *h;
153
154         h = malloc(sizeof(*h));
155         if (!h)
156                 return -ENOMEM;
157
158         h->hash = _get_alg(name);
159         if (!h->hash) {
160                 free(h);
161                 return -EINVAL;
162         }
163
164         h->hash->init(&h->nettle_ctx);
165
166         *ctx = h;
167         return 0;
168 }
169
170 static void crypt_hash_restart(struct crypt_hash *ctx)
171 {
172         ctx->hash->init(&ctx->nettle_ctx);
173 }
174
175 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
176 {
177         ctx->hash->update(&ctx->nettle_ctx, length, (const uint8_t*)buffer);
178         return 0;
179 }
180
181 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
182 {
183         if (length > (size_t)ctx->hash->length)
184                 return -EINVAL;
185
186         ctx->hash->digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
187         crypt_hash_restart(ctx);
188         return 0;
189 }
190
191 int crypt_hash_destroy(struct crypt_hash *ctx)
192 {
193         memset(ctx, 0, sizeof(*ctx));
194         free(ctx);
195         return 0;
196 }
197
198 /* HMAC */
199 int crypt_hmac_size(const char *name)
200 {
201         return crypt_hash_size(name);
202 }
203
204 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
205                     const void *buffer, size_t length)
206 {
207         struct crypt_hmac *h;
208
209         h = malloc(sizeof(*h));
210         if (!h)
211                 return -ENOMEM;
212         memset(ctx, 0, sizeof(*ctx));
213
214
215         h->hash = _get_alg(name);
216         if (!h->hash)
217                 goto bad;
218
219         h->key = malloc(length);
220         if (!h->key)
221                 goto bad;
222
223         memcpy(h->key, buffer, length);
224         h->key_length = length;
225
226         h->hash->init(&h->nettle_ctx);
227         h->hash->hmac_set_key(&h->nettle_ctx, h->key_length, h->key);
228
229         *ctx = h;
230         return 0;
231 bad:
232         free(h);
233         return -EINVAL;
234 }
235
236 static void crypt_hmac_restart(struct crypt_hmac *ctx)
237 {
238         ctx->hash->hmac_set_key(&ctx->nettle_ctx, ctx->key_length, ctx->key);
239 }
240
241 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
242 {
243         ctx->hash->hmac_update(&ctx->nettle_ctx, length, (const uint8_t *)buffer);
244         return 0;
245 }
246
247 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
248 {
249         if (length > (size_t)ctx->hash->length)
250                 return -EINVAL;
251
252         ctx->hash->hmac_digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
253         crypt_hmac_restart(ctx);
254         return 0;
255 }
256
257 int crypt_hmac_destroy(struct crypt_hmac *ctx)
258 {
259         memset(ctx->key, 0, ctx->key_length);
260         memset(ctx, 0, sizeof(*ctx));
261         free(ctx->key);
262         free(ctx);
263         return 0;
264 }