3 #include "crypto_s2k.h"
4 #include "crypto_pwbox.h"
10 1 byte: header len (H)
11 H bytes: header, denoting secret key algorithm.
13 Round up to multiple of 128 bytes, then encrypt:
17 32 bytes: HMAC-SHA256 of all previous bytes.
20 #define MAX_OVERHEAD (S2K_MAXLEN + 8 + 1 + 32 + CIPHER_IV_LEN)
23 * Make an authenticated passphrase-encrypted blob to encode the
24 * <b>input_len</b> bytes in <b>input</b> using the passphrase
25 * <b>secret</b> of <b>secret_len</b> bytes. Allocate a new chunk of memory
26 * to hold the encrypted data, and store a pointer to that memory in
27 * *<b>out</b>, and its size in <b>outlen_out</b>. Use <b>s2k_flags</b> as an
28 * argument to the passphrase-hashing function.
31 crypto_pwbox(uint8_t **out
, size_t *outlen_out
,
32 const uint8_t *input
, size_t input_len
,
33 const char *secret
, size_t secret_len
,
36 uint8_t *result
= NULL
, *encrypted_portion
;
37 size_t encrypted_len
= 128 * CEIL_DIV(input_len
+4, 128);
40 uint8_t keys
[CIPHER_KEY_LEN
+ DIGEST256_LEN
];
41 pwbox_encoded_t
*enc
= NULL
;
44 crypto_cipher_t
*cipher
;
47 enc
= pwbox_encoded_new();
49 pwbox_encoded_setlen_skey_header(enc
, S2K_MAXLEN
);
51 spec_len
= secret_to_key_make_specifier(
52 pwbox_encoded_getarray_skey_header(enc
),
55 if (spec_len
< 0 || spec_len
> S2K_MAXLEN
)
57 pwbox_encoded_setlen_skey_header(enc
, spec_len
);
58 enc
->header_len
= spec_len
;
60 crypto_rand((char*)enc
->iv
, sizeof(enc
->iv
));
62 pwbox_encoded_setlen_data(enc
, encrypted_len
);
63 encrypted_portion
= pwbox_encoded_getarray_data(enc
);
65 set_uint32(encrypted_portion
, htonl((uint32_t)input_len
));
66 memcpy(encrypted_portion
+4, input
, input_len
);
68 /* Now that all the data is in position, derive some keys, encrypt, and
70 if (secret_to_key_derivekey(keys
, sizeof(keys
),
71 pwbox_encoded_getarray_skey_header(enc
),
73 secret
, secret_len
) < 0)
76 cipher
= crypto_cipher_new_with_iv((char*)keys
, (char*)enc
->iv
);
77 crypto_cipher_crypt_inplace(cipher
, (char*)encrypted_portion
, encrypted_len
);
78 crypto_cipher_free(cipher
);
80 result_len
= pwbox_encoded_encoded_len(enc
);
83 result
= tor_malloc(result_len
);
84 enc_len
= pwbox_encoded_encode(result
, result_len
, enc
);
87 tor_assert(enc_len
== result_len
);
89 crypto_hmac_sha256((char*) result
+ result_len
- 32,
90 (const char*)keys
+ CIPHER_KEY_LEN
,
96 *outlen_out
= result_len
;
105 pwbox_encoded_free(enc
);
106 memwipe(keys
, 0, sizeof(keys
));
111 * Try to decrypt the passphrase-encrypted blob of <b>input_len</b> bytes in
112 * <b>input</b> using the passphrase <b>secret</b> of <b>secret_len</b> bytes.
113 * On success, return 0 and allocate a new chunk of memory to hold the
114 * decrypted data, and store a pointer to that memory in *<b>out</b>, and its
115 * size in <b>outlen_out</b>. On failure, return UNPWBOX_BAD_SECRET if
116 * the passphrase might have been wrong, and UNPWBOX_CORRUPT if the object is
117 * definitely corrupt.
120 crypto_unpwbox(uint8_t **out
, size_t *outlen_out
,
121 const uint8_t *inp
, size_t input_len
,
122 const char *secret
, size_t secret_len
)
124 uint8_t *result
= NULL
;
125 const uint8_t *encrypted
;
126 uint8_t keys
[CIPHER_KEY_LEN
+ DIGEST256_LEN
];
127 uint8_t hmac
[DIGEST256_LEN
];
129 size_t encrypted_len
;
130 crypto_cipher_t
*cipher
= NULL
;
131 int rv
= UNPWBOX_CORRUPTED
;
134 pwbox_encoded_t
*enc
= NULL
;
136 got_len
= pwbox_encoded_parse(&enc
, inp
, input_len
);
137 if (got_len
< 0 || (size_t)got_len
!= input_len
)
140 /* Now derive the keys and check the hmac. */
141 if (secret_to_key_derivekey(keys
, sizeof(keys
),
142 pwbox_encoded_getarray_skey_header(enc
),
143 pwbox_encoded_getlen_skey_header(enc
),
144 secret
, secret_len
) < 0)
147 crypto_hmac_sha256((char *)hmac
,
148 (const char*)keys
+ CIPHER_KEY_LEN
, DIGEST256_LEN
,
149 (const char*)inp
, input_len
- DIGEST256_LEN
);
151 if (tor_memneq(hmac
, enc
->hmac
, DIGEST256_LEN
)) {
152 rv
= UNPWBOX_BAD_SECRET
;
156 /* How long is the plaintext? */
157 encrypted
= pwbox_encoded_getarray_data(enc
);
158 encrypted_len
= pwbox_encoded_getlen_data(enc
);
159 if (encrypted_len
< 4)
162 cipher
= crypto_cipher_new_with_iv((char*)keys
, (char*)enc
->iv
);
163 crypto_cipher_decrypt(cipher
, (char*)&result_len
, (char*)encrypted
, 4);
164 result_len
= ntohl(result_len
);
165 if (encrypted_len
< result_len
+ 4)
168 /* Allocate a buffer and decrypt */
169 result
= tor_malloc_zero(result_len
);
170 crypto_cipher_decrypt(cipher
, (char*)result
, (char*)encrypted
+4, result_len
);
173 *outlen_out
= result_len
;
182 crypto_cipher_free(cipher
);
183 pwbox_encoded_free(enc
);
184 memwipe(keys
, 0, sizeof(keys
));