Document <openssl/cast.h>

This is a legacy cipher that no one should be using anymore, but as long
as we have these symbols, we ought to document how you use them. While
I'm here, use the uint8_t foo[N] syntax for the fixed-width fields.
(C doesn't check it, it's just an easy bit of documentation.)

Also fill in some missing bits for <openssl/des.h> too. (DES's CFB code
also needs to be documented, but I haven't stared at that yet.
DESTest.CFB suggests there was something weird, so I'll leave it alone
for now.)

Change-Id: I214cd95391b7162c103a665f38e25dee9579f7c7
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/90527
Reviewed-by: Lily Chen <chlily@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Lily Chen <chlily@google.com>
diff --git a/decrepit/cast/cast.cc b/decrepit/cast/cast.cc
index a2262c2..42d90ce 100644
--- a/decrepit/cast/cast.cc
+++ b/decrepit/cast/cast.cc
@@ -16,9 +16,7 @@
 #include <openssl/cipher.h>
 #include <openssl/obj.h>
 
-#if defined(OPENSSL_WINDOWS)
-#include <intrin.h>
-#endif
+#include <assert.h>
 
 #include "../../crypto/fipsmodule/cipher/internal.h"
 #include "../../crypto/internal.h"
@@ -28,8 +26,8 @@
 
 using namespace bssl;
 
-void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, const CAST_KEY *ks,
-                      int enc) {
+void CAST_ecb_encrypt(const uint8_t in[CAST_BLOCK], uint8_t out[CAST_BLOCK],
+                      const CAST_KEY *ks, int enc) {
   uint32_t d[2];
 
   n2l(in, d[0]);
@@ -56,7 +54,7 @@
          0xffffffffL;                                                \
   }
 
-void CAST_encrypt(uint32_t *data, const CAST_KEY *key) {
+void CAST_encrypt(uint32_t data[2], const CAST_KEY *key) {
   uint32_t l, r, t;
   const uint32_t *k;
 
@@ -88,7 +86,7 @@
   data[0] = r & 0xffffffffL;
 }
 
-void CAST_decrypt(uint32_t *data, const CAST_KEY *key) {
+void CAST_decrypt(uint32_t data[2], const CAST_KEY *key) {
   uint32_t l, r, t;
   const uint32_t *k;
 
@@ -121,7 +119,8 @@
 }
 
 void CAST_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
-                      const CAST_KEY *ks, uint8_t *iv, int enc) {
+                      const CAST_KEY *ks, uint8_t iv[8], int enc) {
+  assert(length % CAST_BLOCK == 0);
   uint32_t tin0, tin1;
   uint32_t tout0, tout1, xor0, xor1;
   size_t l = length;
@@ -311,7 +310,7 @@
 // extra state information to record how much of the 64bit block we have used
 // is contained in *num.
 void CAST_cfb64_encrypt(const uint8_t *in, uint8_t *out, size_t length,
-                        const CAST_KEY *schedule, uint8_t *ivec, int *num,
+                        const CAST_KEY *schedule, uint8_t ivec[8], int *num,
                         int enc) {
   uint32_t v0, v1, t;
   int n = *num;
diff --git a/include/openssl/cast.h b/include/openssl/cast.h
index e410204..cfb708b 100644
--- a/include/openssl/cast.h
+++ b/include/openssl/cast.h
@@ -22,6 +22,15 @@
 #endif
 
 
+// CAST-128.
+//
+// CAST-128 (RFC 2144), also known as CAST5, is a legacy block cipher with
+// 64-bit blocks. It is deprecated and retained for backwards compatibility
+// only. The implementation is not hardened against side channels and may leak
+// secrets via timing or cache side channels.
+//
+// Use a modern cipher, such as AES-GCM or ChaCha20-Poly1305, instead.
+
 #define CAST_ENCRYPT 1
 #define CAST_DECRYPT 0
 
@@ -33,19 +42,45 @@
   int short_key;  // Use reduced rounds for short key
 } CAST_KEY;
 
+// CAST_set_key initializes |key| from |len| bytes of key material starting from
+// |data|. CAST-128 keys are between 5 and 16 bytes long. If |len| is greater
+// than 16, |data| is truncated and only the first 16 bytes are processed. If
+// |len| is less than 5, it is internally zero-padded.
 OPENSSL_EXPORT void CAST_set_key(CAST_KEY *key, size_t len,
                                  const uint8_t *data);
-OPENSSL_EXPORT void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out,
+
+// CAST_ecb_encrypt encrypts (or decrypts, if |enc| is |CAST_DECRYPT|) a single
+// 8-byte block from |in| to |out|, using |key|.
+OPENSSL_EXPORT void CAST_ecb_encrypt(const uint8_t in[CAST_BLOCK],
+                                     uint8_t out[CAST_BLOCK],
                                      const CAST_KEY *key, int enc);
-OPENSSL_EXPORT void CAST_encrypt(uint32_t *data, const CAST_KEY *key);
-OPENSSL_EXPORT void CAST_decrypt(uint32_t *data, const CAST_KEY *key);
+
+// CAST_encrypt encrypts an 8-byte block from |data| in-place with |key|. An
+// 8-byte block is represented in this function as two 32-bit integers,
+// containing the first and second four bytes in big-endian order.
+OPENSSL_EXPORT void CAST_encrypt(uint32_t data[2], const CAST_KEY *key);
+
+// CAST_decrypt decrypts an 8-byte block from |data| in-place with |key|. An
+// 8-byte block is represented in this function as two 32-bit integers,
+// containing the first and second four bytes in big-endian order.
+OPENSSL_EXPORT void CAST_decrypt(uint32_t data[2], const CAST_KEY *key);
+
+// CAST_cbc_encrypt encrypts (or decrypts, if |enc| is |CAST_DECRYPT|) |length|
+// bytes from |in| to |out| with CAST-128 in CBC mode. |length| must be a
+// multiple of 8. The IV is taken from |iv|. When the function completes, the IV
+// for the next block is written to |iv|.
 OPENSSL_EXPORT void CAST_cbc_encrypt(const uint8_t *in, uint8_t *out,
                                      size_t length, const CAST_KEY *ks,
-                                     uint8_t *iv, int enc);
+                                     uint8_t iv[8], int enc);
 
+// CAST_cfb64_encrypt encrypts (or decrypts, if |enc| is |CAST_DECRYPT|)
+// |length| bytes from |in| to |out| with CAST-128 in CFB-64 mode. |length| must
+// be a multiple of 8. On the first call, |*num| should be zero and |ivec| the
+// IV. On exit, this function will write state to |ivec| and |*num| to resume an
+// encryption or decryption operation if the buffers are not contiguous.
 OPENSSL_EXPORT void CAST_cfb64_encrypt(const uint8_t *in, uint8_t *out,
                                        size_t length, const CAST_KEY *schedule,
-                                       uint8_t *ivec, int *num, int enc);
+                                       uint8_t ivec[8], int *num, int enc);
 
 #ifdef __cplusplus
 }  // extern C
diff --git a/include/openssl/des.h b/include/openssl/des.h
index 1c9f5f3..c601391 100644
--- a/include/openssl/des.h
+++ b/include/openssl/des.h
@@ -58,7 +58,7 @@
 OPENSSL_EXPORT void DES_set_odd_parity(DES_cblock *key);
 
 // DES_ecb_encrypt encrypts (or decrypts, if |is_encrypt| is |DES_DECRYPT|) a
-// single DES block (8 bytes) from in to out, using the key configured in
+// single DES block (8 bytes) from |in| to |out|, using the key configured in
 // |schedule|.
 OPENSSL_EXPORT void DES_ecb_encrypt(const DES_cblock *in, DES_cblock *out,
                                     const DES_key_schedule *schedule,
@@ -66,6 +66,8 @@
 
 // DES_ncbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len|
 // bytes from |in| to |out| with DES in CBC mode. |len| must be a multiple of 8.
+// The IV is taken from |ivec|. When the function completes, the IV for the next
+// block is written to |ivec|.
 OPENSSL_EXPORT void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out,
                                      size_t len,
                                      const DES_key_schedule *schedule,
@@ -83,7 +85,8 @@
 // DES_ede3_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len|
 // bytes from |in| to |out| with 3DES in CBC mode. 3DES uses three keys, thus
 // the function takes three different |DES_key_schedule|s. |len| must be a
-// multiple of 8.
+// multiple of 8. The IV is taken from |ivec|. When the function completes, the
+// IV for the next block is written to |ivec|.
 OPENSSL_EXPORT void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out,
                                          size_t len,
                                          const DES_key_schedule *ks1,
@@ -94,7 +97,9 @@
 // DES_ede2_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len|
 // bytes from |in| to |out| with 3DES in CBC mode. With this keying option, the
 // first and third 3DES keys are identical. Thus, this function takes only two
-// different |DES_key_schedule|s. |len| must be a multiple of 8.
+// different |DES_key_schedule|s. |len| must be a multiple of 8. The IV is taken
+// from |ivec|. When the function completes, the IV for the next block is
+// written to |ivec|.
 OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out,
                                          size_t len,
                                          const DES_key_schedule *ks1,