[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 07/11] libcrypto: get compiling with BoringSSL


With this change, libcrypto.c will compile with BoringSSL.  To
get this working here's what I did:

 * Include the libcrypto-boringssl-compat shim header when building
   with OPENSSL_IS_BORINGSSL.

 * Bring in a few more functions to the libcrypto-boringssl-compat
   shim.  Of these functions a couple needed to be adapted for the
   APIs exposed by BoringSSL -- these have been marked with comments
   'BoringSSL Change'.

 * Support for a few old ciphers are disabled now when building
   with OPENSSL_IS_BORINGSSL: "blowfish-cbc", "3des-cbc",
   "des-cbc-ssh1".  Probably these ciphers should be removed
   upstream in general and along with SSH1 support.

Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
 src/libcrypto-boringssl-compat.c | 76 ++++++++++++++++++++++++++++++++++++++++
 src/libcrypto-boringssl-compat.h | 10 ++++++
 src/libcrypto.c                  | 41 +++++++++++++---------
 3 files changed, 110 insertions(+), 17 deletions(-)

diff --git a/src/libcrypto-boringssl-compat.c b/src/libcrypto-boringssl-compat.c
index ac11d1e3..4a954209 100644
--- a/src/libcrypto-boringssl-compat.c
+++ b/src/libcrypto-boringssl-compat.c
@@ -10,6 +10,9 @@
 /*
  * libcrypto-boringssl-compat.c --
  *   OpenSSL compat shim adapted for use by libssh with BoringSSL.
+ *   See comments marked with 'BoringSSL Change' for changes.
+ *
+ *  Jon Simons <jon@xxxxxxxxxxxxx>
  */
 
 #include "config.h"
@@ -22,6 +25,15 @@
 #error "BoringSSL libcrypto compat used for OpenSSL build"
 #endif /* !defined(OPENSSL_IS_BORINGSSL) */
 
+static void *OPENSSL_zalloc(size_t num)
+{
+    void *ret = OPENSSL_malloc(num);
+
+    if (ret != NULL)
+        memset(ret, 0, num);
+    return ret;
+}
+
 int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
 {
     /* If the fields n and e in r are NULL, the corresponding input
@@ -179,3 +191,67 @@ int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
     sig->s = s;
     return 1;
 }
+
+EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
+}
+
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
+{
+    if (ctx == NULL) {
+        return 1;
+    }
+
+    /*
+     * BoringSSL Change:
+     *   Use 'EVP_MD_CTX_cleanup' instead
+     *   of manual free'ing of ctx fields.
+     */
+    return EVP_MD_CTX_cleanup(ctx);
+}
+
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+    EVP_MD_CTX_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+HMAC_CTX *HMAC_CTX_new(void)
+{
+    HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX));
+
+    if (ctx != NULL) {
+        if (!HMAC_CTX_reset(ctx)) {
+            HMAC_CTX_free(ctx);
+            return NULL;
+        }
+    }
+    return ctx;
+}
+
+static void hmac_ctx_cleanup(HMAC_CTX *ctx)
+{
+    /* BoringSSL Change: use HMAC_CTX_cleanup directly. */
+    HMAC_CTX_cleanup(ctx);
+}
+
+void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+    if (ctx != NULL) {
+        hmac_ctx_cleanup(ctx);
+#if OPENSSL_VERSION_NUMBER > 0x10100000L
+        EVP_MD_CTX_free(&ctx->i_ctx);
+        EVP_MD_CTX_free(&ctx->o_ctx);
+        EVP_MD_CTX_free(&ctx->md_ctx);
+#endif
+        OPENSSL_free(ctx);
+    }
+}
+
+int HMAC_CTX_reset(HMAC_CTX *ctx)
+{
+    HMAC_CTX_init(ctx);
+    return 1;
+}
diff --git a/src/libcrypto-boringssl-compat.h b/src/libcrypto-boringssl-compat.h
index 66fed529..c284640b 100644
--- a/src/libcrypto-boringssl-compat.h
+++ b/src/libcrypto-boringssl-compat.h
@@ -11,6 +11,8 @@
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
 #include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
 
 int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
 int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
@@ -25,4 +27,12 @@ int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
 void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
 int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
 
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_new(void);
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+
+HMAC_CTX *HMAC_CTX_new(void);
+int HMAC_CTX_reset(HMAC_CTX *ctx);
+void HMAC_CTX_free(HMAC_CTX *ctx);
+
 #endif /* LIBCRYPTO_BORINGSSL_COMPAT_H */
diff --git a/src/libcrypto.c b/src/libcrypto.c
index 260ccc7a..a29a793e 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -46,16 +46,18 @@
 
 #if !defined(OPENSSL_IS_BORINGSSL)
 #include "libcrypto-compat.h"
+#else  /* !defined(OPENSSL_IS_BORINGSSL) */
+#include "libcrypto-boringssl-compat.h"
 #endif /* !defined(OPENSSL_IS_BORINGSSL) */
 
 #ifdef HAVE_OPENSSL_AES_H
 #define HAS_AES
 #include <openssl/aes.h>
 #endif
-#ifdef HAVE_OPENSSL_DES_H
+#if defined(HAVE_OPENSSL_DES_H) && !defined(OPENSSL_IS_BORINGSSL)
 #define HAS_DES
 #include <openssl/des.h>
-#endif
+#endif /* defined(HAVE_OPENSSL_DES_H) && !defined(OPENSSL_IS_BORINGSSL) */
 
 #if (OPENSSL_VERSION_NUMBER<0x00907000L)
 #define OLD_CRYPTO
@@ -139,19 +141,19 @@ static const EVP_MD *nid_to_evpmd(int nid)
 void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen)
 {
     const EVP_MD *evp_md = nid_to_evpmd(nid);
-    EVP_MD_CTX *md = EVP_MD_CTX_new(); /* TODO: not in BoringSSL */
+    EVP_MD_CTX *md = EVP_MD_CTX_new();
 
     EVP_DigestInit(md, evp_md);
     EVP_DigestUpdate(md, digest, len);
     EVP_DigestFinal(md, hash, hlen);
-    EVP_MD_CTX_free(md); /* TODO: not in BoringSSL */
+    EVP_MD_CTX_free(md);
 }
 
 EVPCTX evp_init(int nid)
 {
     const EVP_MD *evp_md = nid_to_evpmd(nid);
 
-    EVPCTX ctx = EVP_MD_CTX_new(); /* TODO: not in BoringSSL */
+    EVPCTX ctx = EVP_MD_CTX_new();
     if (ctx == NULL) {
         return NULL;
     }
@@ -383,13 +385,13 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
 HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
   HMACCTX ctx = NULL;
 
-  ctx = HMAC_CTX_new(); /* TODO: not in BoringSSL */
+  ctx = HMAC_CTX_new();
   if (ctx == NULL) {
     return NULL;
   }
 
 #ifndef OLD_CRYPTO
-  HMAC_CTX_reset(ctx); // openssl 0.9.7 requires it. /* TODO: not in BoringSSL */
+  HMAC_CTX_reset(ctx); // openssl 0.9.7 requires it.
 #endif
 
   switch(type) {
@@ -409,7 +411,7 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
       HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL);
       break;
     default:
-      HMAC_CTX_free(ctx); /* TODO: not in BoringSSL */
+      HMAC_CTX_free(ctx);
       SAFE_FREE(ctx);
       ctx = NULL;
   }
@@ -469,15 +471,18 @@ static void evp_cipher_init(struct ssh_cipher_struct *cipher) {
     case SSH_3DES_CBC:
         cipher->cipher = EVP_des_ede3_cbc();
         break;
+#if !defined(OPENSSL_IS_BORINGSSL)
     case SSH_BLOWFISH_CBC:
-        cipher->cipher = EVP_bf_cbc(); /* TODO: not in BoringSSL */
+        cipher->cipher = EVP_bf_cbc();
         break;
+#endif /* !defined(OPENSSL_IS_BORINGSSL) */
         /* ciphers not using EVP */
     case SSH_3DES_CBC_SSH1:
     case SSH_DES_CBC_SSH1:
         SSH_LOG(SSH_LOG_WARNING, "This cipher should not use evp_cipher_init");
         break;
     case SSH_NO_CIPHER:
+    default:
         SSH_LOG(SSH_LOG_WARNING, "No valid ciphertype found");
         break;
     }
@@ -652,9 +657,9 @@ static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
 #ifdef DEBUG_CRYPTO
   ssh_print_hexa("Encrypt IV before", cipher->des3_key->ivs.c, 24);
 #endif
-  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 1); /* TODO: BoringSSL signature mismatch */
-  DES_ncbc_encrypt(out, in, len, &cipher->des3_key->keys[1], &cipher->des3_key->ivs.v[1], 0); /* TODO: BoringSSL signature mismatch */
-  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[2], &cipher->des3_key->ivs.v[2], 1); /* TODO: BoringSSL signature mismatch */
+  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 1);
+  DES_ncbc_encrypt(out, in, len, &cipher->des3_key->keys[1], &cipher->des3_key->ivs.v[1], 0);
+  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[2], &cipher->des3_key->ivs.v[2], 1);
 #ifdef DEBUG_CRYPTO
   ssh_print_hexa("Encrypt IV after", cipher->des3_key->ivs.c, 24);
 #endif
@@ -666,9 +671,9 @@ static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
   ssh_print_hexa("Decrypt IV before", cipher->des3_key->ivs.c, 24);
 #endif
 
-  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[2], &cipher->des3_key->ivs.v[0], 0); /* TODO: BoringSSL signature mismatch */
-  DES_ncbc_encrypt(out, in, len, &cipher->des3_key->keys[1], &cipher->des3_key->ivs.v[1], 1); /* TODO: BoringSSL signature mismatch */
-  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[2], 0); /* TODO: BoringSSL signature mismatch */
+  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[2], &cipher->des3_key->ivs.v[0], 0);
+  DES_ncbc_encrypt(out, in, len, &cipher->des3_key->keys[1], &cipher->des3_key->ivs.v[1], 1);
+  DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[2], 0);
 
 #ifdef DEBUG_CRYPTO
   ssh_print_hexa("Decrypt IV after", cipher->des3_key->ivs.c, 24);
@@ -689,12 +694,12 @@ static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
 
 static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
                            unsigned long len){
-    DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 1); /* TODO: BoringSSL signature mismatch */
+    DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 1);
 }
 
 static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
         unsigned long len){
-    DES_ncbc_encrypt(in,out,len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 0); /* TODO: BoringSSL signature mismatch */
+    DES_ncbc_encrypt(in,out,len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 0);
 }
 
 static void des_cleanup(struct ssh_cipher_struct *cipher){
@@ -708,6 +713,7 @@ static void des_cleanup(struct ssh_cipher_struct *cipher){
  * The table of supported ciphers
  */
 static struct ssh_cipher_struct ssh_ciphertab[] = {
+#if !defined(OPENSSL_IS_BORINGSSL)
   {
     .name = "blowfish-cbc",
     .blocksize = 8,
@@ -719,6 +725,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .decrypt = evp_cipher_decrypt,
     .cleanup = evp_cipher_cleanup
   },
+#endif /* !defined(OPENSSL_IS_BORINGSSL) */
 #ifdef HAS_AES
 #ifndef BROKEN_AES_CTR
 /* OpenSSL until 0.9.7c has a broken AES_ctr128_encrypt implementation which
-- 
2.14.1


References:
[PATCH 00/11] libssh: enable building with BoringSSLJon Simons <jon@xxxxxxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org