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

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


On Sunday, 10 September 2017 05:12:50 CET Jon Simons wrote:
> 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

BORING SSL sets the OpenSSL version number to 1.1?

> +        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



Archive administrator: postmaster@lists.cynapses.org