5e4345b34fc4ceb19a28090dd0367e889b4cba71
[platform/upstream/cryptsetup.git] / lib / crypto_backend / crypto_openssl.c
1 /*
2  * OPENSSL crypto backend implementation
3  *
4  * Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
5  * Copyright (C) 2010-2014, 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  * In addition, as a special exception, the copyright holders give
22  * permission to link the code of portions of this program with the
23  * OpenSSL library under certain conditions as described in each
24  * individual source file, and distribute linked combinations
25  * including the two.
26  *
27  * You must obey the GNU Lesser General Public License in all respects
28  * for all of the code used other than OpenSSL.
29  */
30
31 #include <string.h>
32 #include <errno.h>
33 #include <openssl/evp.h>
34 #include <openssl/hmac.h>
35 #include <openssl/rand.h>
36 #include "crypto_backend.h"
37
38 static int crypto_backend_initialised = 0;
39
40 struct crypt_hash {
41         EVP_MD_CTX md;
42         const EVP_MD *hash_id;
43         int hash_len;
44 };
45
46 struct crypt_hmac {
47         HMAC_CTX md;
48         const EVP_MD *hash_id;
49         int hash_len;
50 };
51
52 int crypt_backend_init(struct crypt_device *ctx)
53 {
54         if (crypto_backend_initialised)
55                 return 0;
56
57         OpenSSL_add_all_algorithms();
58
59         crypto_backend_initialised = 1;
60         return 0;
61 }
62
63 uint32_t crypt_backend_flags(void)
64 {
65         return 0;
66 }
67
68 const char *crypt_backend_version(void)
69 {
70         return SSLeay_version(SSLEAY_VERSION);
71 }
72
73 /* HASH */
74 int crypt_hash_size(const char *name)
75 {
76         const EVP_MD *hash_id = EVP_get_digestbyname(name);
77
78         if (!hash_id)
79                 return -EINVAL;
80
81         return EVP_MD_size(hash_id);
82 }
83
84 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
85 {
86         struct crypt_hash *h;
87
88         h = malloc(sizeof(*h));
89         if (!h)
90                 return -ENOMEM;
91
92         h->hash_id = EVP_get_digestbyname(name);
93         if (!h->hash_id) {
94                 free(h);
95                 return -EINVAL;
96         }
97
98         if (EVP_DigestInit(&h->md, h->hash_id) != 1) {
99                 free(h);
100                 return -EINVAL;
101         }
102
103         h->hash_len = EVP_MD_size(h->hash_id);
104         *ctx = h;
105         return 0;
106 }
107
108 static int crypt_hash_restart(struct crypt_hash *ctx)
109 {
110         if (EVP_DigestInit(&ctx->md, ctx->hash_id) != 1)
111                 return -EINVAL;
112
113         return 0;
114 }
115
116 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
117 {
118         if (EVP_DigestUpdate(&ctx->md, buffer, length) != 1)
119                 return -EINVAL;
120
121         return 0;
122 }
123
124 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
125 {
126         unsigned char tmp[EVP_MAX_MD_SIZE];
127         unsigned int tmp_len = 0;
128
129         if (length > (size_t)ctx->hash_len)
130                 return -EINVAL;
131
132         if (EVP_DigestFinal_ex(&ctx->md, tmp, &tmp_len) != 1)
133                 return -EINVAL;
134
135         memcpy(buffer, tmp, length);
136         crypt_backend_memzero(tmp, sizeof(tmp));
137
138         if (tmp_len < length)
139                 return -EINVAL;
140
141         if (crypt_hash_restart(ctx))
142                 return -EINVAL;
143
144         return 0;
145 }
146
147 int crypt_hash_destroy(struct crypt_hash *ctx)
148 {
149         EVP_MD_CTX_cleanup(&ctx->md);
150         memset(ctx, 0, sizeof(*ctx));
151         free(ctx);
152         return 0;
153 }
154
155 /* HMAC */
156 int crypt_hmac_size(const char *name)
157 {
158         return crypt_hash_size(name);
159 }
160
161 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
162                     const void *buffer, size_t length)
163 {
164         struct crypt_hmac *h;
165
166         h = malloc(sizeof(*h));
167         if (!h)
168                 return -ENOMEM;
169
170         h->hash_id = EVP_get_digestbyname(name);
171         if (!h->hash_id) {
172                 free(h);
173                 return -EINVAL;
174         }
175
176         HMAC_CTX_init(&h->md);
177         HMAC_Init_ex(&h->md, buffer, length, h->hash_id, NULL);
178
179         h->hash_len = EVP_MD_size(h->hash_id);
180         *ctx = h;
181         return 0;
182 }
183
184 static void crypt_hmac_restart(struct crypt_hmac *ctx)
185 {
186         HMAC_Init_ex(&ctx->md, NULL, 0, ctx->hash_id, NULL);
187 }
188
189 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
190 {
191         HMAC_Update(&ctx->md, (const unsigned char *)buffer, length);
192         return 0;
193 }
194
195 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
196 {
197         unsigned char tmp[EVP_MAX_MD_SIZE];
198         unsigned int tmp_len = 0;
199
200         if (length > (size_t)ctx->hash_len)
201                 return -EINVAL;
202
203         HMAC_Final(&ctx->md, tmp, &tmp_len);
204
205         memcpy(buffer, tmp, length);
206         crypt_backend_memzero(tmp, sizeof(tmp));
207
208         if (tmp_len < length)
209                 return -EINVAL;
210
211         crypt_hmac_restart(ctx);
212
213         return 0;
214 }
215
216 int crypt_hmac_destroy(struct crypt_hmac *ctx)
217 {
218         HMAC_CTX_cleanup(&ctx->md);
219         memset(ctx, 0, sizeof(*ctx));
220         free(ctx);
221         return 0;
222 }
223
224 /* RNG */
225 int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
226 {
227         if (fips)
228                 return -EINVAL;
229
230         if (RAND_bytes((unsigned char *)buffer, length) != 1)
231                 return -EINVAL;
232
233         return 0;
234 }
235
236 /* PBKDF */
237 int crypt_pbkdf(const char *kdf, const char *hash,
238                 const char *password, size_t password_length,
239                 const char *salt, size_t salt_length,
240                 char *key, size_t key_length,
241                 unsigned int iterations)
242 {
243         const EVP_MD *hash_id;
244
245         if (!kdf || strncmp(kdf, "pbkdf2", 6))
246                 return -EINVAL;
247
248         hash_id = EVP_get_digestbyname(hash);
249         if (!hash_id)
250                 return -EINVAL;
251
252         if (!PKCS5_PBKDF2_HMAC(password, (int)password_length,
253             (unsigned char *)salt, (int)salt_length,
254             (int)iterations, hash_id, (int)key_length, (unsigned char *)key))
255                 return -EINVAL;
256
257         return 0;
258 }