1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "openssl-util.h"
4 #include "alloc-util.h"
5 #include "hexdecoct.h"
6 
7 #if HAVE_OPENSSL
openssl_hash(const EVP_MD * alg,const void * msg,size_t msg_len,uint8_t * ret_hash,size_t * ret_hash_len)8 int openssl_hash(const EVP_MD *alg,
9                  const void *msg,
10                  size_t msg_len,
11                  uint8_t *ret_hash,
12                  size_t *ret_hash_len) {
13 
14         _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = NULL;
15         unsigned len;
16         int r;
17 
18         ctx = EVP_MD_CTX_new();
19         if (!ctx)
20                 /* This function just calls OPENSSL_zalloc, so failure
21                  * here is almost certainly a failed allocation. */
22                 return -ENOMEM;
23 
24         /* The documentation claims EVP_DigestInit behaves just like
25          * EVP_DigestInit_ex if passed NULL, except it also calls
26          * EVP_MD_CTX_reset, which deinitializes the context. */
27         r = EVP_DigestInit_ex(ctx, alg, NULL);
28         if (r == 0)
29                 return -EIO;
30 
31         r = EVP_DigestUpdate(ctx, msg, msg_len);
32         if (r == 0)
33                 return -EIO;
34 
35         r = EVP_DigestFinal_ex(ctx, ret_hash, &len);
36         if (r == 0)
37                 return -EIO;
38 
39         if (ret_hash_len)
40                 *ret_hash_len = len;
41 
42         return 0;
43 }
44 
rsa_encrypt_bytes(EVP_PKEY * pkey,const void * decrypted_key,size_t decrypted_key_size,void ** ret_encrypt_key,size_t * ret_encrypt_key_size)45 int rsa_encrypt_bytes(
46                 EVP_PKEY *pkey,
47                 const void *decrypted_key,
48                 size_t decrypted_key_size,
49                 void **ret_encrypt_key,
50                 size_t *ret_encrypt_key_size) {
51 
52         _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
53         _cleanup_free_ void *b = NULL;
54         size_t l;
55 
56         ctx = EVP_PKEY_CTX_new(pkey, NULL);
57         if (!ctx)
58                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate public key context");
59 
60         if (EVP_PKEY_encrypt_init(ctx) <= 0)
61                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize public key context");
62 
63         if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
64                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to configure PKCS#1 padding");
65 
66         if (EVP_PKEY_encrypt(ctx, NULL, &l, decrypted_key, decrypted_key_size) <= 0)
67                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine encrypted key size");
68 
69         b = malloc(l);
70         if (!b)
71                 return -ENOMEM;
72 
73         if (EVP_PKEY_encrypt(ctx, b, &l, decrypted_key, decrypted_key_size) <= 0)
74                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine encrypted key size");
75 
76         *ret_encrypt_key = TAKE_PTR(b);
77         *ret_encrypt_key_size = l;
78 
79         return 0;
80 }
81 
rsa_pkey_to_suitable_key_size(EVP_PKEY * pkey,size_t * ret_suitable_key_size)82 int rsa_pkey_to_suitable_key_size(
83                 EVP_PKEY *pkey,
84                 size_t *ret_suitable_key_size) {
85 
86         size_t suitable_key_size;
87         int bits;
88 
89         assert_se(pkey);
90         assert_se(ret_suitable_key_size);
91 
92         /* Analyzes the specified public key and that it is RSA. If so, will return a suitable size for a
93          * disk encryption key to encrypt with RSA for use in PKCS#11 security token schemes. */
94 
95         if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA)
96                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "X.509 certificate does not refer to RSA key.");
97 
98         bits = EVP_PKEY_bits(pkey);
99         log_debug("Bits in RSA key: %i", bits);
100 
101         /* We use PKCS#1 padding for the RSA cleartext, hence let's leave some extra space for it, hence only
102          * generate a random key half the size of the RSA length */
103         suitable_key_size = bits / 8 / 2;
104 
105         if (suitable_key_size < 1)
106                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Uh, RSA key size too short?");
107 
108         *ret_suitable_key_size = suitable_key_size;
109         return 0;
110 }
111 
112 #  if PREFER_OPENSSL
string_hashsum(const char * s,size_t len,const EVP_MD * md_algorithm,char ** ret)113 int string_hashsum(
114                 const char *s,
115                 size_t len,
116                 const EVP_MD *md_algorithm,
117                 char **ret) {
118 
119         uint8_t hash[EVP_MAX_MD_SIZE];
120         size_t hash_size;
121         char *enc;
122         int r;
123 
124         hash_size = EVP_MD_size(md_algorithm);
125         assert(hash_size > 0);
126 
127         r = openssl_hash(md_algorithm, s, len, hash, NULL);
128         if (r < 0)
129                 return r;
130 
131         enc = hexmem(hash, hash_size);
132         if (!enc)
133                 return -ENOMEM;
134 
135         *ret = enc;
136         return 0;
137 
138 }
139 #  endif
140 #endif
141