Add Nettle crypto backend support.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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         { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, }
85 };
86
87 struct crypt_hash {
88         const struct hash_alg *hash;
89         union {
90                 struct sha1_ctx sha1;
91                 struct sha224_ctx sha224;
92                 struct sha256_ctx sha256;
93                 struct sha384_ctx sha384;
94                 struct sha512_ctx sha512;
95         } nettle_ctx;
96 };
97
98 struct crypt_hmac {
99         const struct hash_alg *hash;
100         union {
101                 struct hmac_sha1_ctx sha1;
102                 struct hmac_sha224_ctx sha224;
103                 struct hmac_sha256_ctx sha256;
104                 struct hmac_sha384_ctx sha384;
105                 struct hmac_sha512_ctx sha512;
106         } nettle_ctx;
107         size_t key_length;
108         uint8_t *key;
109 };
110
111 uint32_t crypt_backend_flags(void)
112 {
113         return 0;
114 }
115
116 static struct hash_alg *_get_alg(const char *name)
117 {
118         int i = 0;
119
120         while (name && hash_algs[i].name) {
121                 if (!strcmp(name, hash_algs[i].name))
122                         return &hash_algs[i];
123                 i++;
124         }
125         return NULL;
126 }
127
128 int crypt_backend_init(struct crypt_device *ctx)
129 {
130         log_dbg("Initialising Nettle crypto backend.");
131         return 0;
132 }
133
134 /* HASH */
135 int crypt_hash_size(const char *name)
136 {
137         struct hash_alg *ha = _get_alg(name);
138
139         return ha ? ha->length : -EINVAL;
140 }
141
142 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
143 {
144         struct crypt_hash *h;
145
146         h = malloc(sizeof(*h));
147         if (!h)
148                 return -ENOMEM;
149
150         h->hash = _get_alg(name);
151         if (!h->hash) {
152                 free(h);
153                 return -EINVAL;
154         }
155
156         h->hash->init(&h->nettle_ctx);
157
158         *ctx = h;
159         return 0;
160 }
161
162 int crypt_hash_restart(struct crypt_hash *ctx)
163 {
164         ctx->hash->init(&ctx->nettle_ctx);
165         return 0;
166 }
167
168 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
169 {
170         ctx->hash->update(&ctx->nettle_ctx, length, (const uint8_t*)buffer);
171         return 0;
172 }
173
174 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
175 {
176         if (length > (size_t)ctx->hash->length)
177                 return -EINVAL;
178
179         ctx->hash->digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
180         return 0;
181 }
182
183 int crypt_hash_destroy(struct crypt_hash *ctx)
184 {
185         memset(ctx, 0, sizeof(*ctx));
186         free(ctx);
187         return 0;
188 }
189
190 /* HMAC */
191 int crypt_hmac_size(const char *name)
192 {
193         return crypt_hash_size(name);
194 }
195
196 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
197                     const void *buffer, size_t length)
198 {
199         struct crypt_hmac *h;
200
201         h = malloc(sizeof(*h));
202         if (!h)
203                 return -ENOMEM;
204         memset(ctx, 0, sizeof(*ctx));
205
206
207         h->hash = _get_alg(name);
208         if (!h->hash)
209                 goto bad;
210
211         h->key = malloc(length);
212         if (!h->key)
213                 goto bad;
214
215         memcpy(h->key, buffer, length);
216         h->key_length = length;
217
218         h->hash->init(&h->nettle_ctx);
219         h->hash->hmac_set_key(&h->nettle_ctx, h->key_length, h->key);
220
221         *ctx = h;
222         return 0;
223 bad:
224         free(h);
225         return -EINVAL;
226 }
227
228 int crypt_hmac_restart(struct crypt_hmac *ctx)
229 {
230         ctx->hash->hmac_set_key(&ctx->nettle_ctx, ctx->key_length, ctx->key);
231         return 0;
232 }
233
234 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
235 {
236         ctx->hash->hmac_update(&ctx->nettle_ctx, length, (const uint8_t *)buffer);
237         return 0;
238 }
239
240 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
241 {
242         if (length > (size_t)ctx->hash->length)
243                 return -EINVAL;
244
245         ctx->hash->hmac_digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
246         return 0;
247 }
248
249 int crypt_hmac_destroy(struct crypt_hmac *ctx)
250 {
251         memset(ctx->key, 0, ctx->key_length);
252         memset(ctx, 0, sizeof(*ctx));
253         free(ctx->key);
254         free(ctx);
255         return 0;
256 }