]> git.tuebingen.mpg.de Git - paraslash.git/blob - openssl.c
openssl: Switch to evp API for sha1 and sha256.
[paraslash.git] / openssl.c
1 /* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3 /** \file openssl.c Openssl-based encryption/decryption routines. */
4
5 #include <regex.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <openssl/rand.h>
9 #include <openssl/err.h>
10 #include <openssl/pem.h>
11 #include <openssl/sha.h>
12 #include <openssl/bn.h>
13 #include <openssl/aes.h>
14 #include <openssl/evp.h>
15
16 #include "para.h"
17 #include "error.h"
18 #include "string.h"
19 #include "crypt.h"
20 #include "crypt_backend.h"
21 #include "portable_io.h"
22
23 struct asymmetric_key {
24         RSA *rsa;
25 };
26
27 void get_random_bytes_or_die(unsigned char *buf, int num)
28 {
29         unsigned long err;
30
31         /* RAND_bytes() returns 1 on success, 0 otherwise. */
32         if (RAND_bytes(buf, num) == 1)
33                 return;
34         err = ERR_get_error();
35         PARA_EMERG_LOG("%s\n", ERR_reason_error_string(err));
36         exit(EXIT_FAILURE);
37 }
38
39 /*
40  * Read 64 bytes from /dev/urandom and add them to the SSL PRNG. Seed the PRNG
41  * used by random(3) with a random seed obtained from SSL. If /dev/urandom is
42  * not readable, the function calls exit().
43  *
44  * \sa RAND_load_file(3), \ref get_random_bytes_or_die(), srandom(3),
45  * random(3), \ref para_random().
46  */
47 void crypt_init(void)
48 {
49         int seed, ret = RAND_load_file("/dev/urandom", 64);
50
51         if (ret != 64) {
52                 PARA_EMERG_LOG("could not seed PRNG (ret = %d)\n", ret);
53                 exit(EXIT_FAILURE);
54         }
55         get_random_bytes_or_die((unsigned char *)&seed, sizeof(seed));
56         srandom(seed);
57 }
58
59 void crypt_shutdown(void)
60 {
61 #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
62         CRYPTO_cleanup_all_ex_data();
63 #endif
64 #ifdef HAVE_OPENSSL_THREAD_STOP /* openssl-1.1 or later */
65         OPENSSL_thread_stop();
66 #else /* openssl-1.0 */
67         ERR_remove_thread_state(NULL);
68 #endif
69         EVP_cleanup();
70 }
71
72 /*
73  * The public key loading functions below were inspired by corresponding code
74  * of openssh-5.2p1, Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo,
75  * Finland. However, not much of the original code remains.
76  */
77
78 static int read_bignum(const unsigned char *buf, size_t len, BIGNUM **result)
79 {
80         const unsigned char *p = buf, *end = buf + len;
81         uint32_t bnsize;
82         BIGNUM *bn;
83
84         if (p + 4 < p)
85                 return -E_BIGNUM;
86         if (p + 4 > end)
87                 return -E_BIGNUM;
88         bnsize = read_u32_be(p);
89         PARA_DEBUG_LOG("bnsize: %u\n", bnsize);
90         p += 4;
91         if (p + bnsize < p)
92                 return -E_BIGNUM;
93         if (p + bnsize > end)
94                 return -E_BIGNUM;
95         if (bnsize > 8192)
96                 return -E_BIGNUM;
97         bn = BN_bin2bn(p, bnsize, NULL);
98         if (!bn)
99                 return -E_BIGNUM;
100         *result = bn;
101         return bnsize + 4;
102 }
103
104 static int read_rsa_bignums(const unsigned char *blob, int blen, RSA **result)
105 {
106         int ret;
107         RSA *rsa;
108         BIGNUM *n, *e;
109         const unsigned char *p = blob, *end = blob + blen;
110
111         rsa = RSA_new();
112         if (!rsa)
113                 return -E_BIGNUM;
114         ret = read_bignum(p, end - p, &e);
115         if (ret < 0)
116                 goto free_rsa;
117         p += ret;
118         ret = read_bignum(p, end - p, &n);
119         if (ret < 0)
120                 goto free_e;
121 #ifdef HAVE_RSA_SET0_KEY
122         RSA_set0_key(rsa, n, e, NULL);
123 #else
124         rsa->n = n;
125         rsa->e = e;
126 #endif
127         *result = rsa;
128         return 1;
129 free_e:
130         BN_free(e);
131 free_rsa:
132         RSA_free(rsa);
133         return ret;
134 }
135
136 static int read_pem_private_key(const char *path, RSA **rsa)
137 {
138         EVP_PKEY *pkey;
139         BIO *bio = BIO_new(BIO_s_file());
140
141         *rsa = NULL;
142         if (!bio)
143                 return -E_PRIVATE_KEY;
144         if (BIO_read_filename(bio, path) <= 0)
145                 goto bio_free;
146         pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
147         if (!pkey)
148                 goto bio_free;
149         *rsa = EVP_PKEY_get1_RSA(pkey);
150         EVP_PKEY_free(pkey);
151 bio_free:
152         BIO_free(bio);
153         return *rsa? RSA_size(*rsa) : -E_PRIVATE_KEY;
154 }
155
156 static int read_private_rsa_params(const unsigned char *blob,
157                 const unsigned char *end, RSA **result)
158 {
159         int ret;
160         RSA *rsa;
161         BN_CTX *ctx;
162         BIGNUM *n, *e, *d, *iqmp, *p, *q; /* stored in the key file */
163         BIGNUM *dmp1, *dmq1; /* these will be computed */
164         BIGNUM *tmp;
165         const unsigned char *cp = blob;
166
167         rsa = RSA_new();
168         if (!rsa)
169                 return -E_BIGNUM;
170         ret = -E_BIGNUM;
171         tmp = BN_new();
172         if (!tmp)
173                 goto free_rsa;
174         ctx = BN_CTX_new();
175         if (!ctx)
176                 goto free_tmp;
177         dmp1 = BN_new();
178         if (!dmp1)
179                 goto free_ctx;
180         dmq1 = BN_new();
181         if (!dmq1)
182                 goto free_dmp1;
183         ret = read_bignum(cp, end - cp, &n);
184         if (ret < 0)
185                 goto free_dmq1;
186         cp += ret;
187         ret = read_bignum(cp, end - cp, &e);
188         if (ret < 0)
189                 goto free_n;
190         cp += ret;
191         ret = read_bignum(cp, end - cp, &d);
192         if (ret < 0)
193                 goto free_e;
194         cp += ret;
195         ret = read_bignum(cp, end - cp, &iqmp);
196         if (ret < 0)
197                 goto free_d;
198         cp += ret;
199         ret = read_bignum(cp, end - cp, &p);
200         if (ret < 0)
201                 goto free_iqmp;
202         cp += ret;
203         ret = read_bignum(cp, end - cp, &q);
204         if (ret < 0)
205                 goto free_p;
206         ret = -E_BIGNUM;
207         if (!BN_sub(tmp, q, BN_value_one()))
208                 goto free_q;
209         if (!BN_mod(dmp1, d, tmp, ctx))
210                 goto free_q;
211         if (!BN_sub(tmp, q, BN_value_one()))
212                 goto free_q;
213         if (!BN_mod(dmq1, d, tmp, ctx))
214                 goto free_q;
215 #ifdef HAVE_RSA_SET0_KEY
216         RSA_set0_key(rsa, n, e, d);
217         RSA_set0_factors(rsa, p, q);
218         RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
219 #else
220         rsa->n = n;
221         rsa->e = e;
222         rsa->d = d;
223         rsa->p = p;
224         rsa->q = q;
225         rsa->dmp1 = dmp1;
226         rsa->dmq1 = dmq1;
227         rsa->iqmp = iqmp;
228 #endif
229         *result = rsa;
230         ret = 1;
231         goto free_ctx;
232 free_q:
233         BN_clear_free(q);
234 free_p:
235         BN_clear_free(p);
236 free_iqmp:
237         BN_clear_free(iqmp);
238 free_d:
239         BN_clear_free(d);
240 free_e:
241         BN_free(e);
242 free_n:
243         BN_free(n);
244 free_dmq1:
245         BN_clear_free(dmq1);
246 free_dmp1:
247         BN_clear_free(dmp1);
248 free_ctx:
249         BN_CTX_free(ctx);
250 free_tmp:
251         BN_clear_free(tmp);
252 free_rsa:
253         if (ret < 0)
254                 RSA_free(rsa);
255         return ret;
256 }
257
258 static int get_private_key(const char *path, RSA **rsa)
259 {
260         int ret;
261         unsigned char *blob, *end;
262         size_t blob_size;
263
264         *rsa = NULL;
265         ret = decode_private_key(path, &blob, &blob_size);
266         if (ret < 0)
267                 return ret;
268         end = blob + blob_size;
269         if (ret == PKT_OPENSSH) {
270                 ret = find_openssh_bignum_offset(blob, blob_size);
271                 if (ret < 0)
272                         goto free_blob;
273                 PARA_INFO_LOG("reading RSA params at offset %d\n", ret);
274                 ret = read_private_rsa_params(blob + ret, end, rsa);
275         } else
276                 ret = read_pem_private_key(path, rsa);
277 free_blob:
278         free(blob);
279         return ret;
280 }
281
282 int apc_get_pubkey(const char *key_file, struct asymmetric_key **result)
283 {
284         unsigned char *blob;
285         size_t decoded_size;
286         int ret;
287         struct asymmetric_key *key = alloc(sizeof(*key));
288
289         ret = decode_public_key(key_file, &blob, &decoded_size);
290         if (ret < 0)
291                 goto out;
292         ret = read_rsa_bignums(blob + ret, decoded_size - ret, &key->rsa);
293         if (ret < 0)
294                 goto free_blob;
295         ret = RSA_size(key->rsa);
296         assert(ret > 0);
297         *result = key;
298 free_blob:
299         free(blob);
300 out:
301         if (ret < 0) {
302                 free(key);
303                 *result = NULL;
304                 PARA_ERROR_LOG("can not load key %s\n", key_file);
305         }
306         return ret;
307 }
308
309 void apc_free_pubkey(struct asymmetric_key *key)
310 {
311         if (!key)
312                 return;
313         RSA_free(key->rsa);
314         free(key);
315 }
316
317 int apc_priv_decrypt(const char *key_file, unsigned char *outbuf,
318                 unsigned char *inbuf, int inlen)
319 {
320         struct asymmetric_key *priv;
321         int ret;
322
323         ret = check_private_key_file(key_file);
324         if (ret < 0)
325                 return ret;
326         if (inlen < 0)
327                 return -E_RSA;
328         priv = alloc(sizeof(*priv));
329         ret = get_private_key(key_file, &priv->rsa);
330         if (ret < 0) {
331                 free(priv);
332                 return ret;
333         }
334         /*
335          * RSA is vulnerable to timing attacks. Generate a random blinding
336          * factor to protect against this kind of attack.
337          */
338         ret = -E_BLINDING;
339         if (RSA_blinding_on(priv->rsa, NULL) == 0)
340                 goto out;
341         ret = RSA_private_decrypt(inlen, inbuf, outbuf, priv->rsa,
342                 RSA_PKCS1_OAEP_PADDING);
343         RSA_blinding_off(priv->rsa);
344         if (ret <= 0)
345                 ret = -E_DECRYPT;
346 out:
347         RSA_free(priv->rsa);
348         free(priv);
349         return ret;
350 }
351
352 int apc_pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf,
353                 unsigned len, unsigned char *outbuf)
354 {
355         int ret, flen = len; /* RSA_public_encrypt expects a signed int */
356
357         if (flen < 0)
358                 return -E_ENCRYPT;
359         ret = RSA_public_encrypt(flen, inbuf, outbuf, pub->rsa,
360                 RSA_PKCS1_OAEP_PADDING);
361         return ret < 0? -E_ENCRYPT : ret;
362 }
363
364 struct stream_cipher {
365         EVP_CIPHER_CTX *aes;
366 };
367
368 struct stream_cipher *sc_new(const unsigned char *data, int len)
369 {
370         struct stream_cipher *sc = alloc(sizeof(*sc));
371
372         assert(len >= 2 * AES_CRT128_BLOCK_SIZE);
373         sc->aes = EVP_CIPHER_CTX_new();
374         EVP_EncryptInit_ex(sc->aes, EVP_aes_128_ctr(), NULL, data,
375                 data + AES_CRT128_BLOCK_SIZE);
376         return sc;
377 }
378
379 void sc_free(struct stream_cipher *sc)
380 {
381         if (!sc)
382                 return;
383         EVP_CIPHER_CTX_free(sc->aes);
384         free(sc);
385 }
386
387 static void aes_ctr128_crypt(EVP_CIPHER_CTX *ctx, struct iovec *src,
388                 struct iovec *dst)
389 {
390         int ret, inlen = src->iov_len, outlen, tmplen;
391
392         *dst = (typeof(*dst)) {
393                 /* Add one for the terminating zero byte. */
394                 .iov_base = alloc(inlen + 1),
395                 .iov_len = inlen
396         };
397         ret = EVP_EncryptUpdate(ctx, dst->iov_base, &outlen, src->iov_base, inlen);
398         assert(ret != 0);
399         ret = EVP_EncryptFinal_ex(ctx, dst->iov_base + outlen, &tmplen);
400         assert(ret != 0);
401         outlen += tmplen;
402         ((char *)dst->iov_base)[outlen] = '\0';
403         dst->iov_len = outlen;
404 }
405
406 void sc_crypt(struct stream_cipher *sc, struct iovec *src, struct iovec *dst)
407 {
408         return aes_ctr128_crypt(sc->aes, src, dst);
409 }
410
411 void hash_function(const char *data, unsigned long len, unsigned char *hash)
412 {
413         EVP_MD_CTX *c = EVP_MD_CTX_new();
414         int ret = EVP_DigestInit_ex(c, EVP_sha1(), NULL);
415         assert(ret != 0);
416         ret = EVP_DigestUpdate(c, data, len);
417         assert(ret != 0);
418         ret = EVP_DigestFinal_ex(c, hash, NULL);
419         assert(ret != 0);
420         EVP_MD_CTX_free(c);
421 }
422
423 void hash2_function(const char *data, unsigned long len, unsigned char *hash)
424 {
425         EVP_MD_CTX *c = EVP_MD_CTX_new();
426         int ret = EVP_DigestInit_ex(c, EVP_sha256(), NULL);
427         assert(ret != 0);
428         ret = EVP_DigestUpdate(c, data, len);
429         assert(ret != 0);
430         ret = EVP_DigestFinal_ex(c, hash, NULL);
431         assert(ret != 0);
432         EVP_MD_CTX_free(c);
433 }