Replicate s3_cbc.c under crypto/cipher/internal.h.
These helper functions will be used in the implementation of the legacy CBC
mode AEADs. The file is copied as-is and then modified to remove the dependency
on ssl/. Notably explicit IV logic is removed (that's a side effect of how
explicit IVs are currently implemented) and the padding length is returned
directly rather than smuggled into rec->type.
(Diffing tls_cbc.c and s3_cbc.c is probably the easiest for a review.)
The helpers are currently unused.
Change-Id: Ib703f4d3620196c9f2921cb3b8bf985f2d1777db
Reviewed-on: https://boringssl-review.googlesource.com/2691
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/cipher/internal.h b/crypto/cipher/internal.h
index d46a9e6..e73d4a1 100644
--- a/crypto/cipher/internal.h
+++ b/crypto/cipher/internal.h
@@ -130,6 +130,76 @@
const uint8_t *ad, size_t ad_len);
};
+
+/* EVP_ssl3_cbc_remove_padding determines the padding from the decrypted, SSLv3,
+ * CBC record in |in|. It sets |*out_len| to the length with the padding removed
+ * or |in_len| if invalid.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ * 0: (in non-constant time) if the record is publicly invalid.
+ * 1: if the padding was valid
+ * -1: otherwise. */
+int EVP_ssl3_cbc_remove_padding(unsigned *out_len,
+ const uint8_t *in, unsigned in_len,
+ unsigned block_size, unsigned mac_size);
+
+/* EVP_tls1_cbc_get_padding determines the padding from the decrypted, TLS, CBC
+ * record in |in|. This decrypted record should not include any "decrypted"
+ * explicit IV. It sets |*out_len| to the length with the padding removed or
+ * |in_len| if invalid.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ * 0: (in non-constant time) if the record is publicly invalid.
+ * 1: if the padding was valid
+ * -1: otherwise. */
+int EVP_tls1_cbc_remove_padding(unsigned *out_len,
+ const uint8_t *in, unsigned in_len,
+ unsigned block_size, unsigned mac_size);
+
+/* EVP_ssl3_cbc_copy_mac copies |md_size| bytes from the end of the first
+ * |in_len| bytes of |in| to |out| in constant time (independent of the concrete
+ * value of |in_len|, which may vary within a 256-byte window). |in| must point
+ * to a buffer of |orig_len| bytes.
+ *
+ * On entry:
+ * orig_len >= in_len >= md_size
+ * md_size <= EVP_MAX_MD_SIZE */
+void EVP_ssl3_cbc_copy_mac(uint8_t *out, unsigned md_size,
+ const uint8_t *in, unsigned in_len,
+ unsigned orig_len);
+
+/* EVP_ssl3_cbc_record_digest_supported returns 1 iff |md| is a hash function
+ * which EVP_ssl3_cbc_digest_record supports. */
+int EVP_ssl3_cbc_record_digest_supported(const EVP_MD *md);
+
+/* EVP_ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
+ * record.
+ *
+ * md: the hash function used in the SSLv3 MAC or HMAC.
+ * ssl3_cbc_record_digest_supported must return true for this hash.
+ * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
+ * md_out_size: the number of output bytes is written here.
+ * header: the 13-byte, TLS record header.
+ * data: the record data itself
+ * data_plus_mac_size: the secret, reported length of the data and MAC
+ * once the padding has been removed.
+ * data_plus_mac_plus_padding_size: the public length of the whole
+ * record, including padding.
+ * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS.
+ *
+ * On entry: by virtue of having been through one of the remove_padding
+ * functions, above, we know that data_plus_mac_size is large enough to contain
+ * a padding byte and MAC. (If the padding was invalid, it might contain the
+ * padding too. ) */
+int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
+ size_t *md_out_size, const uint8_t header[13],
+ const uint8_t *data, size_t data_plus_mac_size,
+ size_t data_plus_mac_plus_padding_size,
+ const uint8_t *mac_secret,
+ unsigned mac_secret_length, char is_sslv3);
+
#if defined(__cplusplus)
} /* extern C */
#endif