Merge branch 'reenc' of https://code.google.com/p/cryptsetup into reenc
[platform/upstream/cryptsetup.git] / lib / crypto_backend / crypto_nettle.c
1 /*
2  * Nettle crypto backend implementation
3  *
4  * Copyright (C) 2011-2012 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 static char *version = "Nettle";
28
29 typedef void (*init_func) (void *);
30 typedef void (*update_func) (void *, unsigned, const uint8_t *);
31 typedef void (*digest_func) (void *, unsigned, uint8_t *);
32 typedef void (*set_key_func) (void *, unsigned, const uint8_t *);
33
34 struct hash_alg {
35         const char *name;
36         int length;
37         init_func init;
38         update_func update;
39         digest_func digest;
40         update_func hmac_update;
41         digest_func hmac_digest;
42         set_key_func hmac_set_key;
43 };
44
45 static struct hash_alg hash_algs[] = {
46         { "sha1", SHA1_DIGEST_SIZE,
47                 (init_func) sha1_init,
48                 (update_func) sha1_update,
49                 (digest_func) sha1_digest,
50                 (update_func) hmac_sha1_update,
51                 (digest_func) hmac_sha1_digest,
52                 (set_key_func) hmac_sha1_set_key,
53         },
54         { "sha224", SHA224_DIGEST_SIZE,
55                 (init_func) sha224_init,
56                 (update_func) sha224_update,
57                 (digest_func) sha224_digest,
58                 (update_func) hmac_sha224_update,
59                 (digest_func) hmac_sha224_digest,
60                 (set_key_func) hmac_sha224_set_key,
61         },
62         { "sha256", SHA256_DIGEST_SIZE,
63                 (init_func) sha256_init,
64                 (update_func) sha256_update,
65                 (digest_func) sha256_digest,
66                 (update_func) hmac_sha256_update,
67                 (digest_func) hmac_sha256_digest,
68                 (set_key_func) hmac_sha256_set_key,
69         },
70         { "sha384", SHA384_DIGEST_SIZE,
71                 (init_func) sha384_init,
72                 (update_func) sha384_update,
73                 (digest_func) sha384_digest,
74                 (update_func) hmac_sha384_update,
75                 (digest_func) hmac_sha384_digest,
76                 (set_key_func) hmac_sha384_set_key,
77         },
78         { "sha512", SHA512_DIGEST_SIZE,
79                 (init_func) sha512_init,
80                 (update_func) sha512_update,
81                 (digest_func) sha512_digest,
82                 (update_func) hmac_sha512_update,
83                 (digest_func) hmac_sha512_digest,
84                 (set_key_func) hmac_sha512_set_key,
85         },
86         { "ripemd160", RIPEMD160_DIGEST_SIZE,
87                 (init_func) ripemd160_init,
88                 (update_func) ripemd160_update,
89                 (digest_func) ripemd160_digest,
90                 (update_func) hmac_ripemd160_update,
91                 (digest_func) hmac_ripemd160_digest,
92                 (set_key_func) hmac_ripemd160_set_key,
93         },
94         { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, }
95 };
96
97 struct crypt_hash {
98         const struct hash_alg *hash;
99         union {
100                 struct sha1_ctx sha1;
101                 struct sha224_ctx sha224;
102                 struct sha256_ctx sha256;
103                 struct sha384_ctx sha384;
104                 struct sha512_ctx sha512;
105         } nettle_ctx;
106 };
107
108 struct crypt_hmac {
109         const struct hash_alg *hash;
110         union {
111                 struct hmac_sha1_ctx sha1;
112                 struct hmac_sha224_ctx sha224;
113                 struct hmac_sha256_ctx sha256;
114                 struct hmac_sha384_ctx sha384;
115                 struct hmac_sha512_ctx sha512;
116         } nettle_ctx;
117         size_t key_length;
118         uint8_t *key;
119 };
120
121 uint32_t crypt_backend_flags(void)
122 {
123         return 0;
124 }
125
126 static struct hash_alg *_get_alg(const char *name)
127 {
128         int i = 0;
129
130         while (name && hash_algs[i].name) {
131                 if (!strcmp(name, hash_algs[i].name))
132                         return &hash_algs[i];
133                 i++;
134         }
135         return NULL;
136 }
137
138 int crypt_backend_init(struct crypt_device *ctx)
139 {
140         return 0;
141 }
142
143 const char *crypt_backend_version(void)
144 {
145         return version;
146 }
147
148 /* HASH */
149 int crypt_hash_size(const char *name)
150 {
151         struct hash_alg *ha = _get_alg(name);
152
153         return ha ? ha->length : -EINVAL;
154 }
155
156 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
157 {
158         struct crypt_hash *h;
159
160         h = malloc(sizeof(*h));
161         if (!h)
162                 return -ENOMEM;
163
164         h->hash = _get_alg(name);
165         if (!h->hash) {
166                 free(h);
167                 return -EINVAL;
168         }
169
170         h->hash->init(&h->nettle_ctx);
171
172         *ctx = h;
173         return 0;
174 }
175
176 static void crypt_hash_restart(struct crypt_hash *ctx)
177 {
178         ctx->hash->init(&ctx->nettle_ctx);
179 }
180
181 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
182 {
183         ctx->hash->update(&ctx->nettle_ctx, length, (const uint8_t*)buffer);
184         return 0;
185 }
186
187 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
188 {
189         if (length > (size_t)ctx->hash->length)
190                 return -EINVAL;
191
192         ctx->hash->digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
193         crypt_hash_restart(ctx);
194         return 0;
195 }
196
197 int crypt_hash_destroy(struct crypt_hash *ctx)
198 {
199         memset(ctx, 0, sizeof(*ctx));
200         free(ctx);
201         return 0;
202 }
203
204 /* HMAC */
205 int crypt_hmac_size(const char *name)
206 {
207         return crypt_hash_size(name);
208 }
209
210 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
211                     const void *buffer, size_t length)
212 {
213         struct crypt_hmac *h;
214
215         h = malloc(sizeof(*h));
216         if (!h)
217                 return -ENOMEM;
218         memset(ctx, 0, sizeof(*ctx));
219
220
221         h->hash = _get_alg(name);
222         if (!h->hash)
223                 goto bad;
224
225         h->key = malloc(length);
226         if (!h->key)
227                 goto bad;
228
229         memcpy(h->key, buffer, length);
230         h->key_length = length;
231
232         h->hash->init(&h->nettle_ctx);
233         h->hash->hmac_set_key(&h->nettle_ctx, h->key_length, h->key);
234
235         *ctx = h;
236         return 0;
237 bad:
238         free(h);
239         return -EINVAL;
240 }
241
242 static void crypt_hmac_restart(struct crypt_hmac *ctx)
243 {
244         ctx->hash->hmac_set_key(&ctx->nettle_ctx, ctx->key_length, ctx->key);
245 }
246
247 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
248 {
249         ctx->hash->hmac_update(&ctx->nettle_ctx, length, (const uint8_t *)buffer);
250         return 0;
251 }
252
253 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
254 {
255         if (length > (size_t)ctx->hash->length)
256                 return -EINVAL;
257
258         ctx->hash->hmac_digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
259         crypt_hmac_restart(ctx);
260         return 0;
261 }
262
263 int crypt_hmac_destroy(struct crypt_hmac *ctx)
264 {
265         memset(ctx->key, 0, ctx->key_length);
266         memset(ctx, 0, sizeof(*ctx));
267         free(ctx->key);
268         free(ctx);
269         return 0;
270 }
271
272 /* RNG - N/A */
273 int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
274 {
275         return -EINVAL;
276 }