f141432e81c0f7999c28ba20c8c577100bb1abd7
[platform/upstream/cryptsetup.git] / lib / crypto_backend / crypto_nss.c
1 /*
2  * NSS crypto backend implementation
3  *
4  * Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
5  * Copyright (C) 2010-2020 Milan Broz
6  *
7  * This file is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this file; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <string.h>
23 #include <errno.h>
24 #include <nss.h>
25 #include <pk11pub.h>
26 #include "crypto_backend_internal.h"
27
28 #define CONST_CAST(x) (x)(uintptr_t)
29
30 static int crypto_backend_initialised = 0;
31 static char version[64];
32
33 struct hash_alg {
34         const char *name;
35         SECOidTag oid;
36         CK_MECHANISM_TYPE ck_type;
37         int length;
38         unsigned int block_length;
39 };
40
41 static struct hash_alg hash_algs[] = {
42         { "sha1",   SEC_OID_SHA1,   CKM_SHA_1_HMAC,  20,  64 },
43         { "sha256", SEC_OID_SHA256, CKM_SHA256_HMAC, 32,  64 },
44         { "sha384", SEC_OID_SHA384, CKM_SHA384_HMAC, 48, 128 },
45         { "sha512", SEC_OID_SHA512, CKM_SHA512_HMAC, 64, 128 },
46 //      { "ripemd160", SEC_OID_RIPEMD160, CKM_RIPEMD160_HMAC, 20, 64 },
47         { NULL, 0, 0, 0 }
48 };
49
50 struct crypt_hash {
51         PK11Context *md;
52         const struct hash_alg *hash;
53 };
54
55 struct crypt_hmac {
56         PK11Context *md;
57         PK11SymKey *key;
58         PK11SlotInfo *slot;
59         const struct hash_alg *hash;
60 };
61
62 struct crypt_cipher {
63         struct crypt_cipher_kernel ck;
64 };
65
66 static struct hash_alg *_get_alg(const char *name)
67 {
68         int i = 0;
69
70         while (name && hash_algs[i].name) {
71                 if (!strcmp(name, hash_algs[i].name))
72                         return &hash_algs[i];
73                 i++;
74         }
75         return NULL;
76 }
77
78 int crypt_backend_init(void)
79 {
80         if (crypto_backend_initialised)
81                 return 0;
82
83         if (NSS_NoDB_Init(".") != SECSuccess)
84                 return -EINVAL;
85
86 #if HAVE_DECL_NSS_GETVERSION
87         snprintf(version, 64, "NSS %s", NSS_GetVersion());
88 #else
89         snprintf(version, 64, "NSS");
90 #endif
91         crypto_backend_initialised = 1;
92         return 0;
93 }
94
95 void crypt_backend_destroy(void)
96 {
97         crypto_backend_initialised = 0;
98 }
99
100 uint32_t crypt_backend_flags(void)
101 {
102         return 0;
103 }
104
105 const char *crypt_backend_version(void)
106 {
107         return crypto_backend_initialised ? version : "";
108 }
109
110 /* HASH */
111 int crypt_hash_size(const char *name)
112 {
113         struct hash_alg *ha = _get_alg(name);
114
115         return ha ? ha->length : -EINVAL;
116 }
117
118 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
119 {
120         struct crypt_hash *h;
121
122         h = malloc(sizeof(*h));
123         if (!h)
124                 return -ENOMEM;
125
126         h->hash = _get_alg(name);
127         if (!h->hash) {
128                 free(h);
129                 return -EINVAL;
130         }
131
132         h->md = PK11_CreateDigestContext(h->hash->oid);
133         if (!h->md) {
134                 free(h);
135                 return -EINVAL;
136         }
137
138         if (PK11_DigestBegin(h->md) != SECSuccess) {
139                 PK11_DestroyContext(h->md, PR_TRUE);
140                 free(h);
141                 return -EINVAL;
142         }
143
144         *ctx = h;
145         return 0;
146 }
147
148 static int crypt_hash_restart(struct crypt_hash *ctx)
149 {
150         if (PK11_DigestBegin(ctx->md) != SECSuccess)
151                 return -EINVAL;
152
153         return 0;
154 }
155
156 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
157 {
158         if (PK11_DigestOp(ctx->md, CONST_CAST(unsigned char *)buffer, length) != SECSuccess)
159                 return -EINVAL;
160
161         return 0;
162 }
163
164 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
165 {
166         unsigned char tmp[64];
167         unsigned int tmp_len;
168
169         if (length > (size_t)ctx->hash->length)
170                 return -EINVAL;
171
172         if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
173                 return -EINVAL;
174
175         memcpy(buffer, tmp, length);
176         crypt_backend_memzero(tmp, sizeof(tmp));
177
178         if (tmp_len < length)
179                 return -EINVAL;
180
181         if (crypt_hash_restart(ctx))
182                 return -EINVAL;
183
184         return 0;
185 }
186
187 void crypt_hash_destroy(struct crypt_hash *ctx)
188 {
189         PK11_DestroyContext(ctx->md, PR_TRUE);
190         memset(ctx, 0, sizeof(*ctx));
191         free(ctx);
192 }
193
194 /* HMAC */
195 int crypt_hmac_size(const char *name)
196 {
197         return crypt_hash_size(name);
198 }
199
200 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
201                     const void *key, size_t key_length)
202 {
203         struct crypt_hmac *h;
204         SECItem keyItem;
205         SECItem noParams;
206
207         keyItem.type = siBuffer;
208         keyItem.data = CONST_CAST(unsigned char *)key;
209         keyItem.len = (int)key_length;
210
211         noParams.type = siBuffer;
212         noParams.data = 0;
213         noParams.len = 0;
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->slot = PK11_GetInternalKeySlot();
226         if (!h->slot)
227                 goto bad;
228
229         h->key = PK11_ImportSymKey(h->slot, h->hash->ck_type, PK11_OriginUnwrap,
230                                    CKA_SIGN,  &keyItem, NULL);
231         if (!h->key)
232                 goto bad;
233
234         h->md = PK11_CreateContextBySymKey(h->hash->ck_type, CKA_SIGN, h->key,
235                                            &noParams);
236         if (!h->md)
237                 goto bad;
238
239         if (PK11_DigestBegin(h->md) != SECSuccess)
240                 goto bad;
241
242         *ctx = h;
243         return 0;
244 bad:
245         crypt_hmac_destroy(h);
246         return -EINVAL;
247 }
248
249 static int crypt_hmac_restart(struct crypt_hmac *ctx)
250 {
251         if (PK11_DigestBegin(ctx->md) != SECSuccess)
252                 return -EINVAL;
253
254         return 0;
255 }
256
257 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
258 {
259         if (PK11_DigestOp(ctx->md, CONST_CAST(unsigned char *)buffer, length) != SECSuccess)
260                 return -EINVAL;
261
262         return 0;
263 }
264
265 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
266 {
267         unsigned char tmp[64];
268         unsigned int tmp_len;
269
270         if (length > (size_t)ctx->hash->length)
271                 return -EINVAL;
272
273         if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
274                 return -EINVAL;
275
276         memcpy(buffer, tmp, length);
277         crypt_backend_memzero(tmp, sizeof(tmp));
278
279         if (tmp_len < length)
280                 return -EINVAL;
281
282         if (crypt_hmac_restart(ctx))
283                 return -EINVAL;
284
285         return 0;
286 }
287
288 void crypt_hmac_destroy(struct crypt_hmac *ctx)
289 {
290         if (ctx->key)
291                 PK11_FreeSymKey(ctx->key);
292         if (ctx->slot)
293                 PK11_FreeSlot(ctx->slot);
294         if (ctx->md)
295                 PK11_DestroyContext(ctx->md, PR_TRUE);
296         memset(ctx, 0, sizeof(*ctx));
297         free(ctx);
298 }
299
300 /* RNG */
301 int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
302 {
303         if (fips)
304                 return -EINVAL;
305
306         if (PK11_GenerateRandom((unsigned char *)buffer, length) != SECSuccess)
307                 return -EINVAL;
308
309         return 0;
310 }
311
312 /* PBKDF */
313 int crypt_pbkdf(const char *kdf, const char *hash,
314                 const char *password, size_t password_length,
315                 const char *salt, size_t salt_length,
316                 char *key, size_t key_length,
317                 uint32_t iterations, uint32_t memory, uint32_t parallel)
318 {
319         struct hash_alg *ha;
320
321         if (!kdf)
322                 return -EINVAL;
323
324         if (!strcmp(kdf, "pbkdf2")) {
325                 ha = _get_alg(hash);
326                 if (!ha)
327                         return -EINVAL;
328
329                 return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
330                                     iterations, key_length, key, ha->block_length);
331         } else if (!strncmp(kdf, "argon2", 6)) {
332                 return argon2(kdf, password, password_length, salt, salt_length,
333                               key, key_length, iterations, memory, parallel);
334         }
335
336         return -EINVAL;
337 }
338
339 /* Block ciphers */
340 int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
341                     const char *mode, const void *key, size_t key_length)
342 {
343         struct crypt_cipher *h;
344         int r;
345
346         h = malloc(sizeof(*h));
347         if (!h)
348                 return -ENOMEM;
349
350         r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length);
351         if (r < 0) {
352                 free(h);
353                 return r;
354         }
355
356         *ctx = h;
357         return 0;
358 }
359
360 void crypt_cipher_destroy(struct crypt_cipher *ctx)
361 {
362         crypt_cipher_destroy_kernel(&ctx->ck);
363         free(ctx);
364 }
365
366 int crypt_cipher_encrypt(struct crypt_cipher *ctx,
367                          const char *in, char *out, size_t length,
368                          const char *iv, size_t iv_length)
369 {
370         return crypt_cipher_encrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
371 }
372
373 int crypt_cipher_decrypt(struct crypt_cipher *ctx,
374                          const char *in, char *out, size_t length,
375                          const char *iv, size_t iv_length)
376 {
377         return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
378 }
379
380 bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
381 {
382         return true;
383 }
384
385 int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
386                             const char *in, char *out, size_t length,
387                             const char *iv, size_t iv_length,
388                             const char *tag, size_t tag_length)
389 {
390         return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
391                                               iv, iv_length, tag, tag_length);
392 }