1 /* Copyright (c) 2014-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
7 * \brief Code for encrypting secrets in a password-protected form and saving
13 #include "lib/arch/bytes.h"
14 #include "lib/crypt_ops/crypto_cipher.h"
15 #include "lib/crypt_ops/crypto_digest.h"
16 #include "lib/crypt_ops/crypto_pwbox.h"
17 #include "lib/crypt_ops/crypto_rand.h"
18 #include "lib/crypt_ops/crypto_s2k.h"
19 #include "lib/crypt_ops/crypto_util.h"
20 #include "lib/ctime/di_ops.h"
21 #include "lib/intmath/muldiv.h"
22 #include "trunnel/pwbox.h"
23 #include "lib/log/util_bug.h"
26 1 byte: header len (H)
27 H bytes: header, denoting secret key algorithm.
29 Round up to multiple of 128 bytes, then encrypt:
33 32 bytes: HMAC-SHA256 of all previous bytes.
36 #define MAX_OVERHEAD (S2K_MAXLEN + 8 + 1 + 32 + CIPHER_IV_LEN)
39 * Make an authenticated passphrase-encrypted blob to encode the
40 * <b>input_len</b> bytes in <b>input</b> using the passphrase
41 * <b>secret</b> of <b>secret_len</b> bytes. Allocate a new chunk of memory
42 * to hold the encrypted data, and store a pointer to that memory in
43 * *<b>out</b>, and its size in <b>outlen_out</b>. Use <b>s2k_flags</b> as an
44 * argument to the passphrase-hashing function.
47 crypto_pwbox(uint8_t **out
, size_t *outlen_out
,
48 const uint8_t *input
, size_t input_len
,
49 const char *secret
, size_t secret_len
,
52 uint8_t *result
= NULL
, *encrypted_portion
;
53 size_t encrypted_len
= 128 * CEIL_DIV(input_len
+4, 128);
56 uint8_t keys
[CIPHER_KEY_LEN
+ DIGEST256_LEN
];
57 pwbox_encoded_t
*enc
= NULL
;
60 crypto_cipher_t
*cipher
;
63 enc
= pwbox_encoded_new();
66 pwbox_encoded_setlen_skey_header(enc
, S2K_MAXLEN
);
68 spec_len
= secret_to_key_make_specifier(
69 pwbox_encoded_getarray_skey_header(enc
),
72 if (BUG(spec_len
< 0 || spec_len
> S2K_MAXLEN
))
74 pwbox_encoded_setlen_skey_header(enc
, spec_len
);
75 enc
->header_len
= spec_len
;
77 crypto_rand((char*)enc
->iv
, sizeof(enc
->iv
));
79 pwbox_encoded_setlen_data(enc
, encrypted_len
);
80 encrypted_portion
= pwbox_encoded_getarray_data(enc
);
82 set_uint32(encrypted_portion
, tor_htonl((uint32_t)input_len
));
83 memcpy(encrypted_portion
+4, input
, input_len
);
85 /* Now that all the data is in position, derive some keys, encrypt, and
87 const int s2k_rv
= secret_to_key_derivekey(keys
, sizeof(keys
),
88 pwbox_encoded_getarray_skey_header(enc
),
94 cipher
= crypto_cipher_new_with_iv((char*)keys
, (char*)enc
->iv
);
95 crypto_cipher_crypt_inplace(cipher
, (char*)encrypted_portion
, encrypted_len
);
96 crypto_cipher_free(cipher
);
98 result_len
= pwbox_encoded_encoded_len(enc
);
99 if (BUG(result_len
< 0))
101 result
= tor_malloc(result_len
);
102 enc_len
= pwbox_encoded_encode(result
, result_len
, enc
);
103 if (BUG(enc_len
< 0))
105 tor_assert(enc_len
== result_len
);
107 crypto_hmac_sha256((char*) result
+ result_len
- 32,
108 (const char*)keys
+ CIPHER_KEY_LEN
,
114 *outlen_out
= result_len
;
120 This error case is often unreachable if we're correctly coded, unless
121 somebody adds a new error case somewhere, or unless you're building
122 without scrypto support.
124 - make_specifier can't fail, unless S2K_MAX_LEN is too short.
125 - secret_to_key_derivekey can't really fail unless we're missing
126 scrypt, or the underlying function fails, or we pass it a bogus
127 algorithm or parameters.
128 - pwbox_encoded_encoded_len can't fail unless we're using trunnel
130 - pwbox_encoded_encode can't fail unless we're using trunnel wrong,
138 pwbox_encoded_free(enc
);
139 memwipe(keys
, 0, sizeof(keys
));
144 * Try to decrypt the passphrase-encrypted blob of <b>input_len</b> bytes in
145 * <b>input</b> using the passphrase <b>secret</b> of <b>secret_len</b> bytes.
146 * On success, return 0 and allocate a new chunk of memory to hold the
147 * decrypted data, and store a pointer to that memory in *<b>out</b>, and its
148 * size in <b>outlen_out</b>. On failure, return UNPWBOX_BAD_SECRET if
149 * the passphrase might have been wrong, and UNPWBOX_CORRUPT if the object is
150 * definitely corrupt.
153 crypto_unpwbox(uint8_t **out
, size_t *outlen_out
,
154 const uint8_t *inp
, size_t input_len
,
155 const char *secret
, size_t secret_len
)
157 uint8_t *result
= NULL
;
158 const uint8_t *encrypted
;
159 uint8_t keys
[CIPHER_KEY_LEN
+ DIGEST256_LEN
];
160 uint8_t hmac
[DIGEST256_LEN
];
162 size_t encrypted_len
;
163 crypto_cipher_t
*cipher
= NULL
;
164 int rv
= UNPWBOX_CORRUPTED
;
167 pwbox_encoded_t
*enc
= NULL
;
169 got_len
= pwbox_encoded_parse(&enc
, inp
, input_len
);
170 if (got_len
< 0 || (size_t)got_len
!= input_len
)
173 /* Now derive the keys and check the hmac. */
174 if (secret_to_key_derivekey(keys
, sizeof(keys
),
175 pwbox_encoded_getarray_skey_header(enc
),
176 pwbox_encoded_getlen_skey_header(enc
),
177 secret
, secret_len
) < 0)
180 crypto_hmac_sha256((char *)hmac
,
181 (const char*)keys
+ CIPHER_KEY_LEN
, DIGEST256_LEN
,
182 (const char*)inp
, input_len
- DIGEST256_LEN
);
184 if (tor_memneq(hmac
, enc
->hmac
, DIGEST256_LEN
)) {
185 rv
= UNPWBOX_BAD_SECRET
;
189 /* How long is the plaintext? */
190 encrypted
= pwbox_encoded_getarray_data(enc
);
191 encrypted_len
= pwbox_encoded_getlen_data(enc
);
192 if (encrypted_len
< 4)
195 cipher
= crypto_cipher_new_with_iv((char*)keys
, (char*)enc
->iv
);
196 crypto_cipher_decrypt(cipher
, (char*)&result_len
, (char*)encrypted
, 4);
197 result_len
= tor_ntohl(result_len
);
198 if (encrypted_len
< result_len
+ 4)
201 /* Allocate a buffer and decrypt */
202 result
= tor_malloc_zero(result_len
);
203 crypto_cipher_decrypt(cipher
, (char*)result
, (char*)encrypted
+4, result_len
);
206 *outlen_out
= result_len
;
215 crypto_cipher_free(cipher
);
216 pwbox_encoded_free(enc
);
217 memwipe(keys
, 0, sizeof(keys
));