s2n_composite_cipher_aes_sha.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include <openssl/aes.h>
  16. #include <openssl/evp.h>
  17. #include <openssl/sha.h>
  18. #include "crypto/s2n_cipher.h"
  19. #include "crypto/s2n_fips.h"
  20. #include "crypto/s2n_openssl.h"
  21. #include "tls/s2n_crypto.h"
  22. #include "utils/s2n_blob.h"
  23. #include "utils/s2n_safety.h"
  24. /* LibreSSL and BoringSSL support the cipher, but the interface is different from Openssl's. We
  25. * should define a separate s2n_cipher struct for LibreSSL and BoringSSL.
  26. */
  27. #if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
  28. /* Symbols for AES-SHA1-CBC composite ciphers were added in Openssl 1.0.1
  29. * These composite ciphers exhibit erratic behavior in LibreSSL releases.
  30. */
  31. #if S2N_OPENSSL_VERSION_AT_LEAST(1, 0, 1)
  32. #define S2N_AES_SHA1_COMPOSITE_AVAILABLE
  33. #endif
  34. #if defined(AWSLC_API_VERSION) && (AWSLC_API_VERSION <= 17)
  35. #undef S2N_AES_SHA1_COMPOSITE_AVAILABLE
  36. #endif
  37. /* Symbols for AES-SHA256-CBC composite ciphers were added in Openssl 1.0.2
  38. * See https://www.openssl.org/news/cl102.txt
  39. * These composite ciphers exhibit erratic behavior in LibreSSL releases.
  40. */
  41. #if S2N_OPENSSL_VERSION_AT_LEAST(1, 0, 2)
  42. #define S2N_AES_SHA256_COMPOSITE_AVAILABLE
  43. #endif
  44. #if defined(AWSLC_API_VERSION) && (AWSLC_API_VERSION <= 17)
  45. #undef S2N_AES_SHA256_COMPOSITE_AVAILABLE
  46. #endif
  47. #endif
  48. /* Silly accessors, but we avoid using version macro guards in multiple places */
  49. static const EVP_CIPHER *s2n_evp_aes_128_cbc_hmac_sha1(void)
  50. {
  51. #if defined(S2N_AES_SHA1_COMPOSITE_AVAILABLE)
  52. return EVP_aes_128_cbc_hmac_sha1();
  53. #else
  54. return NULL;
  55. #endif
  56. }
  57. static const EVP_CIPHER *s2n_evp_aes_256_cbc_hmac_sha1(void)
  58. {
  59. #if defined(S2N_AES_SHA1_COMPOSITE_AVAILABLE)
  60. return EVP_aes_256_cbc_hmac_sha1();
  61. #else
  62. return NULL;
  63. #endif
  64. }
  65. static const EVP_CIPHER *s2n_evp_aes_128_cbc_hmac_sha256(void)
  66. {
  67. #if defined(S2N_AES_SHA256_COMPOSITE_AVAILABLE)
  68. return EVP_aes_128_cbc_hmac_sha256();
  69. #else
  70. return NULL;
  71. #endif
  72. }
  73. static const EVP_CIPHER *s2n_evp_aes_256_cbc_hmac_sha256(void)
  74. {
  75. #if defined(S2N_AES_SHA256_COMPOSITE_AVAILABLE)
  76. return EVP_aes_256_cbc_hmac_sha256();
  77. #else
  78. return NULL;
  79. #endif
  80. }
  81. static uint8_t s2n_composite_cipher_aes128_sha_available(void)
  82. {
  83. /* EVP_aes_128_cbc_hmac_sha1() returns NULL if the implementations aren't available.
  84. * See https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L952
  85. *
  86. * Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
  87. * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
  88. * ciphers cause OpenSSL errors due to the lack of the flag.
  89. */
  90. return (!s2n_is_in_fips_mode() && s2n_evp_aes_128_cbc_hmac_sha1() ? 1 : 0);
  91. }
  92. static uint8_t s2n_composite_cipher_aes256_sha_available(void)
  93. {
  94. /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
  95. * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
  96. * ciphers cause OpenSSL errors due to the lack of the flag.
  97. */
  98. return (!s2n_is_in_fips_mode() && s2n_evp_aes_256_cbc_hmac_sha1() ? 1 : 0);
  99. }
  100. static uint8_t s2n_composite_cipher_aes128_sha256_available(void)
  101. {
  102. /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
  103. * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
  104. * ciphers cause OpenSSL errors due to the lack of the flag.
  105. */
  106. return (!s2n_is_in_fips_mode() && s2n_evp_aes_128_cbc_hmac_sha256() ? 1 : 0);
  107. }
  108. static uint8_t s2n_composite_cipher_aes256_sha256_available(void)
  109. {
  110. /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
  111. * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
  112. * ciphers cause OpenSSL errors due to the lack of the flag.
  113. */
  114. return (!s2n_is_in_fips_mode() && s2n_evp_aes_256_cbc_hmac_sha256() ? 1 : 0);
  115. }
  116. static int s2n_composite_cipher_aes_sha_initial_hmac(struct s2n_session_key *key, uint8_t *sequence_number, uint8_t content_type,
  117. uint16_t protocol_version, uint16_t payload_and_eiv_len, int *extra)
  118. {
  119. /* BoringSSL and AWS-LC(AWSLC_API_VERSION <= 17) do not support these composite ciphers with the existing EVP API, and they took out the
  120. * constants used below. This method should never be called with BoringSSL or AWS-LC(AWSLC_API_VERSION <= 17) because the isAvaliable checked
  121. * will fail. Instead of defining a possibly dangerous default or hard coding this to 0x16 error out with BoringSSL and AWS-LC(AWSLC_API_VERSION <= 17).
  122. */
  123. #if defined(OPENSSL_IS_BORINGSSL) || (defined(AWSLC_API_VERSION) && (AWSLC_API_VERSION <= 17))
  124. POSIX_BAIL(S2N_ERR_NO_SUPPORTED_LIBCRYPTO_API);
  125. #else
  126. uint8_t ctrl_buf[S2N_TLS12_AAD_LEN];
  127. struct s2n_blob ctrl_blob = { 0 };
  128. POSIX_GUARD(s2n_blob_init(&ctrl_blob, ctrl_buf, S2N_TLS12_AAD_LEN));
  129. struct s2n_stuffer ctrl_stuffer = { 0 };
  130. POSIX_GUARD(s2n_stuffer_init(&ctrl_stuffer, &ctrl_blob));
  131. POSIX_GUARD(s2n_stuffer_write_bytes(&ctrl_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
  132. POSIX_GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, content_type));
  133. POSIX_GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version / 10));
  134. POSIX_GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version % 10));
  135. POSIX_GUARD(s2n_stuffer_write_uint16(&ctrl_stuffer, payload_and_eiv_len));
  136. /* This will unnecessarily mangle the input buffer, which is fine since it's temporary
  137. * Return value will be length of digest, padding, and padding length byte.
  138. * See https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L814
  139. * and https://github.com/openssl/openssl/blob/4f0c475719defd7c051964ef9964cc6e5b3a63bf/ssl/record/ssl3_record.c#L743
  140. */
  141. int ctrl_ret = EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_TLS1_AAD, S2N_TLS12_AAD_LEN, ctrl_buf);
  142. S2N_ERROR_IF(ctrl_ret <= 0, S2N_ERR_INITIAL_HMAC);
  143. *extra = ctrl_ret;
  144. return 0;
  145. #endif
  146. }
  147. static int s2n_composite_cipher_aes_sha_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
  148. {
  149. POSIX_ENSURE_EQ(out->size, in->size);
  150. POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
  151. /* len is set by EVP_EncryptUpdate and checked post operation */
  152. int len = 0;
  153. POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
  154. POSIX_ENSURE((int64_t) len == (int64_t) in->size, S2N_ERR_ENCRYPT);
  155. return 0;
  156. }
  157. static int s2n_composite_cipher_aes_sha_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
  158. {
  159. POSIX_ENSURE_EQ(out->size, in->size);
  160. POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
  161. /* len is set by EVP_DecryptUpdate. It is not checked here but padding is manually removed and therefore
  162. * the decryption operation is validated. */
  163. int len = 0;
  164. POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
  165. return 0;
  166. }
  167. static int s2n_composite_cipher_aes_sha_set_mac_write_key(struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size)
  168. {
  169. POSIX_ENSURE_EQ(mac_size, SHA_DIGEST_LENGTH);
  170. EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key);
  171. return 0;
  172. }
  173. static int s2n_composite_cipher_aes_sha256_set_mac_write_key(struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size)
  174. {
  175. POSIX_ENSURE_EQ(mac_size, SHA256_DIGEST_LENGTH);
  176. EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key);
  177. return 0;
  178. }
  179. static int s2n_composite_cipher_aes128_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  180. {
  181. POSIX_ENSURE_EQ(in->size, 16);
  182. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  183. EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
  184. return 0;
  185. }
  186. static int s2n_composite_cipher_aes128_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  187. {
  188. POSIX_ENSURE_EQ(in->size, 16);
  189. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  190. EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
  191. return 0;
  192. }
  193. static int s2n_composite_cipher_aes256_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  194. {
  195. POSIX_ENSURE_EQ(in->size, 32);
  196. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  197. EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
  198. return 0;
  199. }
  200. static int s2n_composite_cipher_aes256_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  201. {
  202. POSIX_ENSURE_EQ(in->size, 32);
  203. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  204. EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
  205. return 0;
  206. }
  207. static int s2n_composite_cipher_aes128_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  208. {
  209. POSIX_ENSURE_EQ(in->size, 16);
  210. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  211. EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
  212. return 0;
  213. }
  214. static int s2n_composite_cipher_aes128_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  215. {
  216. POSIX_ENSURE_EQ(in->size, 16);
  217. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  218. EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
  219. return 0;
  220. }
  221. static int s2n_composite_cipher_aes256_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  222. {
  223. POSIX_ENSURE_EQ(in->size, 32);
  224. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  225. EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
  226. return 0;
  227. }
  228. static int s2n_composite_cipher_aes256_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
  229. {
  230. POSIX_ENSURE_EQ(in->size, 32);
  231. EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
  232. EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
  233. return 0;
  234. }
  235. static int s2n_composite_cipher_aes_sha_init(struct s2n_session_key *key)
  236. {
  237. s2n_evp_ctx_init(key->evp_cipher_ctx);
  238. return 0;
  239. }
  240. static int s2n_composite_cipher_aes_sha_destroy_key(struct s2n_session_key *key)
  241. {
  242. EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
  243. return 0;
  244. }
  245. const struct s2n_cipher s2n_aes128_sha = {
  246. .key_material_size = 16,
  247. .type = S2N_COMPOSITE,
  248. .io.comp = {
  249. .block_size = 16,
  250. .record_iv_size = 16,
  251. .mac_key_size = SHA_DIGEST_LENGTH,
  252. .decrypt = s2n_composite_cipher_aes_sha_decrypt,
  253. .encrypt = s2n_composite_cipher_aes_sha_encrypt,
  254. .set_mac_write_key = s2n_composite_cipher_aes_sha_set_mac_write_key,
  255. .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
  256. .is_available = s2n_composite_cipher_aes128_sha_available,
  257. .init = s2n_composite_cipher_aes_sha_init,
  258. .set_encryption_key = s2n_composite_cipher_aes128_sha_set_encryption_key,
  259. .set_decryption_key = s2n_composite_cipher_aes128_sha_set_decryption_key,
  260. .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
  261. };
  262. const struct s2n_cipher s2n_aes256_sha = {
  263. .key_material_size = 32,
  264. .type = S2N_COMPOSITE,
  265. .io.comp = {
  266. .block_size = 16,
  267. .record_iv_size = 16,
  268. .mac_key_size = SHA_DIGEST_LENGTH,
  269. .decrypt = s2n_composite_cipher_aes_sha_decrypt,
  270. .encrypt = s2n_composite_cipher_aes_sha_encrypt,
  271. .set_mac_write_key = s2n_composite_cipher_aes_sha_set_mac_write_key,
  272. .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
  273. .is_available = s2n_composite_cipher_aes256_sha_available,
  274. .init = s2n_composite_cipher_aes_sha_init,
  275. .set_encryption_key = s2n_composite_cipher_aes256_sha_set_encryption_key,
  276. .set_decryption_key = s2n_composite_cipher_aes256_sha_set_decryption_key,
  277. .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
  278. };
  279. const struct s2n_cipher s2n_aes128_sha256 = {
  280. .key_material_size = 16,
  281. .type = S2N_COMPOSITE,
  282. .io.comp = {
  283. .block_size = 16,
  284. .record_iv_size = 16,
  285. .mac_key_size = SHA256_DIGEST_LENGTH,
  286. .decrypt = s2n_composite_cipher_aes_sha_decrypt,
  287. .encrypt = s2n_composite_cipher_aes_sha_encrypt,
  288. .set_mac_write_key = s2n_composite_cipher_aes_sha256_set_mac_write_key,
  289. .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
  290. .is_available = s2n_composite_cipher_aes128_sha256_available,
  291. .init = s2n_composite_cipher_aes_sha_init,
  292. .set_encryption_key = s2n_composite_cipher_aes128_sha256_set_encryption_key,
  293. .set_decryption_key = s2n_composite_cipher_aes128_sha256_set_decryption_key,
  294. .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
  295. };
  296. const struct s2n_cipher s2n_aes256_sha256 = {
  297. .key_material_size = 32,
  298. .type = S2N_COMPOSITE,
  299. .io.comp = {
  300. .block_size = 16,
  301. .record_iv_size = 16,
  302. .mac_key_size = SHA256_DIGEST_LENGTH,
  303. .decrypt = s2n_composite_cipher_aes_sha_decrypt,
  304. .encrypt = s2n_composite_cipher_aes_sha_encrypt,
  305. .set_mac_write_key = s2n_composite_cipher_aes_sha256_set_mac_write_key,
  306. .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
  307. .is_available = s2n_composite_cipher_aes256_sha256_available,
  308. .init = s2n_composite_cipher_aes_sha_init,
  309. .set_encryption_key = s2n_composite_cipher_aes256_sha256_set_encryption_key,
  310. .set_decryption_key = s2n_composite_cipher_aes256_sha256_set_decryption_key,
  311. .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
  312. };