krb5 commit: Use the supported version of openssl 3's CTS mode

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/b1b0ed0011e575103d05819939751d9658705f0a
commit b1b0ed0011e575103d05819939751d9658705f0a
Author: Robbie Harwood <[email protected]>
Date:   Tue Aug 17 17:11:19 2021 -0400

    Use the supported version of openssl 3's CTS mode
    
    Fixes deprecation warnings about AES_cbc_encrypt and friends.

 src/lib/crypto/openssl/enc_provider/aes.c      |   90 ++++++++++++++++++++++++
 src/lib/crypto/openssl/enc_provider/camellia.c |   90 ++++++++++++++++++++++++
 2 files changed, 180 insertions(+), 0 deletions(-)

diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c
index de2abe3..4c6ef36 100644
--- a/src/lib/crypto/openssl/enc_provider/aes.c
+++ b/src/lib/crypto/openssl/enc_provider/aes.c
@@ -29,8 +29,12 @@
 #ifdef K5_OPENSSL_AES
 
 #include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/core_names.h>
+#else
 #include <openssl/aes.h>
 #include <openssl/modes.h>
+#endif
 
 /* proto's */
 static krb5_error_code
@@ -129,6 +133,90 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
     return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL;
 }
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+static krb5_error_code
+do_cts(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+       size_t num_data, size_t dlen, int encrypt)
+{
+    krb5_error_code ret;
+    int outlen, len;
+    unsigned char *oblock = NULL, *dbuf = NULL;
+    unsigned char iv_cts[IV_CTS_BUF_SIZE];
+    struct iov_cursor cursor;
+    OSSL_PARAM params[2], *p = params;
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *cipher = NULL;
+
+    memset(iv_cts, 0, sizeof(iv_cts));
+    if (ivec != NULL && ivec->data != NULL){
+        if (ivec->length != sizeof(iv_cts))
+            return KRB5_CRYPTO_INTERNAL;
+        memcpy(iv_cts, ivec->data, ivec->length);
+    }
+
+    if (key->keyblock.length == 16)
+        cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC-CTS", NULL);
+    else if (key->keyblock.length == 32)
+        cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC-CTS", NULL);
+    if (cipher == NULL)
+        return KRB5_CRYPTO_INTERNAL;
+
+    oblock = OPENSSL_malloc(dlen);
+    dbuf = OPENSSL_malloc(dlen);
+    ctx = EVP_CIPHER_CTX_new();
+    if (oblock == NULL || dbuf == NULL || ctx == NULL) {
+        ret = ENOMEM;
+        goto cleanup;
+    }
+
+    k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE);
+    k5_iov_cursor_get(&cursor, dbuf);
+
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE,
+                                            "CS3", 0);
+    *p = OSSL_PARAM_construct_end();
+    if (!EVP_CipherInit_ex2(ctx, cipher, key->keyblock.contents, iv_cts,
+                            encrypt, params) ||
+        !EVP_CipherUpdate(ctx, oblock, &outlen, dbuf, dlen) ||
+        !EVP_CipherFinal_ex(ctx, oblock + outlen, &len)) {
+        ret = KRB5_CRYPTO_INTERNAL;
+        goto cleanup;
+    }
+
+    if (ivec != NULL && ivec->data != NULL &&
+        !EVP_CIPHER_CTX_get_updated_iv(ctx, ivec->data, sizeof(iv_cts))) {
+        ret = KRB5_CRYPTO_INTERNAL;
+        goto cleanup;
+    }
+
+    k5_iov_cursor_put(&cursor, oblock);
+
+    ret = 0;
+cleanup:
+    OPENSSL_clear_free(oblock, dlen);
+    OPENSSL_clear_free(dbuf, dlen);
+    EVP_CIPHER_CTX_free(ctx);
+    EVP_CIPHER_free(cipher);
+    return ret;
+}
+
+static inline krb5_error_code
+cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen)
+{
+    return do_cts(key, ivec, data, num_data, dlen, 1);
+}
+
+static inline krb5_error_code
+cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen)
+{
+    return do_cts(key, ivec, data, num_data, dlen, 0);
+}
+
+#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+
 static krb5_error_code
 cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
          size_t num_data, size_t dlen)
@@ -234,6 +322,8 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
     return ret;
 }
 
+#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+
 krb5_error_code
 krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec,
                     krb5_crypto_iov *data, size_t num_data)
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 14c5a62..ac1bcbb 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -27,7 +27,11 @@
 #include "crypto_int.h"
 #include <openssl/evp.h>
 #include <openssl/camellia.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/core_names.h>
+#else
 #include <openssl/modes.h>
+#endif
 
 #ifdef K5_OPENSSL_CAMELLIA
 
@@ -152,6 +156,90 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
     return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL;
 }
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+static krb5_error_code
+do_cts(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+       size_t num_data, size_t dlen, int encrypt)
+{
+    krb5_error_code ret;
+    int outlen, len;
+    unsigned char *oblock = NULL, *dbuf = NULL;
+    unsigned char iv_cts[IV_CTS_BUF_SIZE];
+    struct iov_cursor cursor;
+    OSSL_PARAM params[2], *p = params;
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *cipher = NULL;
+
+    memset(iv_cts, 0, sizeof(iv_cts));
+    if (ivec != NULL && ivec->data != NULL){
+        if (ivec->length != sizeof(iv_cts))
+            return KRB5_CRYPTO_INTERNAL;
+        memcpy(iv_cts, ivec->data, ivec->length);
+    }
+
+    if (key->keyblock.length == 16)
+        cipher = EVP_CIPHER_fetch(NULL, "CAMELLIA-128-CBC-CTS", NULL);
+    else if (key->keyblock.length == 32)
+        cipher = EVP_CIPHER_fetch(NULL, "CAMELLIA-256-CBC-CTS", NULL);
+    if (cipher == NULL)
+        return KRB5_CRYPTO_INTERNAL;
+
+    oblock = OPENSSL_malloc(dlen);
+    dbuf = OPENSSL_malloc(dlen);
+    ctx = EVP_CIPHER_CTX_new();
+    if (oblock == NULL || dbuf == NULL || ctx == NULL) {
+        ret = ENOMEM;
+        goto cleanup;
+    }
+
+    k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE);
+    k5_iov_cursor_get(&cursor, dbuf);
+
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE,
+                                            "CS3", 0);
+    *p = OSSL_PARAM_construct_end();
+    if (!EVP_CipherInit_ex2(ctx, cipher, key->keyblock.contents, iv_cts,
+                            encrypt, params) ||
+        !EVP_CipherUpdate(ctx, oblock, &outlen, dbuf, dlen) ||
+        !EVP_CipherFinal_ex(ctx, oblock + outlen, &len)) {
+        ret = KRB5_CRYPTO_INTERNAL;
+        goto cleanup;
+    }
+
+    if (ivec != NULL && ivec->data != NULL &&
+        !EVP_CIPHER_CTX_get_updated_iv(ctx, ivec->data, sizeof(iv_cts))) {
+        ret = KRB5_CRYPTO_INTERNAL;
+        goto cleanup;
+    }
+
+    k5_iov_cursor_put(&cursor, oblock);
+
+    ret = 0;
+cleanup:
+    OPENSSL_clear_free(oblock, dlen);
+    OPENSSL_clear_free(dbuf, dlen);
+    EVP_CIPHER_CTX_free(ctx);
+    EVP_CIPHER_free(cipher);
+    return ret;
+}
+
+static inline krb5_error_code
+cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen)
+{
+    return do_cts(key, ivec, data, num_data, dlen, 1);
+}
+
+static inline krb5_error_code
+cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen)
+{
+    return do_cts(key, ivec, data, num_data, dlen, 0);
+}
+
+#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+
 static krb5_error_code
 cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
          size_t num_data, size_t dlen)
@@ -257,6 +345,8 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
     return ret;
 }
 
+#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+
 static krb5_error_code
 krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
                          krb5_crypto_iov *data, size_t num_data)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.