[openssl] master update

shane.lontis at oracle.com shane.lontis at oracle.com
Fri Jan 10 02:10:27 UTC 2020


The branch master has been updated
       via  11b44359862632e283feabf15dab85bb550ebace (commit)
      from  1e8879691ff86bda75b6e2e66c0f528684df5d47 (commit)


- Log -----------------------------------------------------------------
commit 11b44359862632e283feabf15dab85bb550ebace
Author: Shane Lontis <shane.lontis at oracle.com>
Date:   Mon Oct 14 20:59:31 2019 +1000

    Add GCM support for EVP_CTRL_GCM_IV_GEN and EVP_CTRL_GCM_SET_IV_INV to providers
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10173)

-----------------------------------------------------------------------

Summary of changes:
 crypto/evp/evp_enc.c                               | 20 ++++-
 doc/man7/provider-cipher.pod                       | 12 +++
 include/openssl/core_names.h                       | 42 +++++-----
 providers/implementations/ciphers/ciphercommon.c   |  2 +
 .../implementations/ciphers/ciphercommon_gcm.c     | 97 +++++++++++++++-------
 5 files changed, 118 insertions(+), 55 deletions(-)

diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index c650addbd1..35feec17f6 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -1135,10 +1135,22 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
             return 0;
         params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz);
         break;
-    case EVP_CTRL_GCM_SET_IV_FIXED:
-        params[0] =
-            OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED,
-                                              ptr, sz);
+    case EVP_CTRL_AEAD_SET_IV_FIXED:
+        params[0] = OSSL_PARAM_construct_octet_string(
+                        OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, ptr, sz);
+        break;
+    case EVP_CTRL_GCM_IV_GEN:
+        set_params = 0;
+        if (arg < 0)
+            sz = 0; /* special case that uses the iv length */
+        params[0] = OSSL_PARAM_construct_octet_string(
+                        OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, ptr, sz);
+        break;
+    case EVP_CTRL_GCM_SET_IV_INV:
+        if (arg < 0)
+            return 0;
+        params[0] = OSSL_PARAM_construct_octet_string(
+                        OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, ptr, sz);
         break;
     case EVP_CTRL_GET_RC5_ROUNDS:
         set_params = 0; /* Fall thru */
diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod
index 7ad239bcb6..80bba1f978 100644
--- a/doc/man7/provider-cipher.pod
+++ b/doc/man7/provider-cipher.pod
@@ -349,6 +349,18 @@ by AES SIV ciphers which disallow multiple operations by default.
 Setting "speed" to 1 allows another encrypt or decrypt operation to be
 performed. This is used for performance testing.
 
+=item "tlsivgen" (B<OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN>) <octet string>
+
+Gets the invocation field generated for encryption.
+Can only be called after "tlsivfixed" is set.
+This is only used for GCM mode.
+
+=item "tlsivinv" (B<OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV>) <octet string>
+
+Sets the invocation field used for decryption.
+Can only be called after "tlsivfixed" is set.
+This is only used for GCM mode.
+
 =item "tls1multi_enc" (B<OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC>) <octet string>
 
 Triggers a multiblock tls1 encrypt operation for a tls1 aware cipher that supports
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 446af5fa8e..db9cb9ab2d 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -51,27 +51,29 @@ extern "C" {
 #define OSSL_ALG_PARAM_PROPERTIES   "properties"/* utf8_string */
 
 /* cipher parameters */
-#define OSSL_CIPHER_PARAM_PADDING   "padding"    /* uint */
-#define OSSL_CIPHER_PARAM_MODE      "mode"       /* uint */
-#define OSSL_CIPHER_PARAM_BLOCK_SIZE "blocksize" /* size_t */
-#define OSSL_CIPHER_PARAM_FLAGS     "flags"      /* ulong */
-#define OSSL_CIPHER_PARAM_KEYLEN    "keylen"     /* size_t */
-#define OSSL_CIPHER_PARAM_IVLEN     "ivlen"      /* size_t */
-#define OSSL_CIPHER_PARAM_IV        "iv"         /* octet_string OR octet_ptr */
-#define OSSL_CIPHER_PARAM_NUM       "num"        /* uint */
-#define OSSL_CIPHER_PARAM_ROUNDS    "rounds"     /* uint */
-#define OSSL_CIPHER_PARAM_AEAD_TAG           "tag"        /* octet_string */
-#define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD      "tlsaad"     /* octet_string */
-#define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD  "tlsaadpad"  /* size_t */
-#define OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED "tlsivfixed" /* octet_string */
-#define OSSL_CIPHER_PARAM_AEAD_IVLEN         OSSL_CIPHER_PARAM_IVLEN
-#define OSSL_CIPHER_PARAM_AEAD_TAGLEN        "taglen"     /* size_t */
-#define OSSL_CIPHER_PARAM_AEAD_MAC_KEY       "mackey"     /* octet_string */
-#define OSSL_CIPHER_PARAM_RANDOM_KEY         "randkey"    /* octet_string */
-#define OSSL_CIPHER_PARAM_RC2_KEYBITS        "keybits"    /* size_t */
-#define OSSL_CIPHER_PARAM_SPEED              "speed"      /* uint */
+#define OSSL_CIPHER_PARAM_PADDING              "padding"    /* uint */
+#define OSSL_CIPHER_PARAM_MODE                 "mode"       /* uint */
+#define OSSL_CIPHER_PARAM_BLOCK_SIZE           "blocksize" /* size_t */
+#define OSSL_CIPHER_PARAM_FLAGS                "flags"      /* ulong */
+#define OSSL_CIPHER_PARAM_KEYLEN               "keylen"     /* size_t */
+#define OSSL_CIPHER_PARAM_IVLEN                "ivlen"      /* size_t */
+#define OSSL_CIPHER_PARAM_IV                   "iv"         /* octet_string OR octet_ptr */
+#define OSSL_CIPHER_PARAM_NUM                  "num"        /* uint */
+#define OSSL_CIPHER_PARAM_ROUNDS               "rounds"     /* uint */
+#define OSSL_CIPHER_PARAM_AEAD_TAG             "tag"        /* octet_string */
+#define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD        "tlsaad"     /* octet_string */
+#define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD    "tlsaadpad"  /* size_t */
+#define OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED   "tlsivfixed" /* octet_string */
+#define OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN "tlsivgen" /* octet_string */
+#define OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV "tlsivinv" /* octet_string */
+#define OSSL_CIPHER_PARAM_AEAD_IVLEN           OSSL_CIPHER_PARAM_IVLEN
+#define OSSL_CIPHER_PARAM_AEAD_TAGLEN          "taglen"     /* size_t */
+#define OSSL_CIPHER_PARAM_AEAD_MAC_KEY         "mackey"     /* octet_string */
+#define OSSL_CIPHER_PARAM_RANDOM_KEY           "randkey"    /* octet_string */
+#define OSSL_CIPHER_PARAM_RC2_KEYBITS          "keybits"    /* size_t */
+#define OSSL_CIPHER_PARAM_SPEED                "speed"      /* uint */
 /* For passing the AlgorithmIdentifier parameter in DER form */
-#define OSSL_CIPHER_PARAM_ALG_ID             "alg_id_param" /* octet_string */
+#define OSSL_CIPHER_PARAM_ALG_ID               "alg_id_param" /* octet_string */
 
 #define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT                    \
     "tls1multi_maxsndfrag" /* uint */
diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c
index a6b890704e..967622cf64 100644
--- a/providers/implementations/ciphers/ciphercommon.c
+++ b/providers/implementations/ciphers/ciphercommon.c
@@ -109,6 +109,7 @@ static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = {
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
+    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0),
     OSSL_PARAM_END
 };
 const OSSL_PARAM *cipher_aead_gettable_ctx_params(void)
@@ -121,6 +122,7 @@ static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0),
     OSSL_PARAM_END
 };
 const OSSL_PARAM *cipher_aead_settable_ctx_params(void)
diff --git a/providers/implementations/ciphers/ciphercommon_gcm.c b/providers/implementations/ciphers/ciphercommon_gcm.c
index 803f810a30..a6928e1ba3 100644
--- a/providers/implementations/ciphers/ciphercommon_gcm.c
+++ b/providers/implementations/ciphers/ciphercommon_gcm.c
@@ -77,6 +77,54 @@ int gcm_dinit(void *vctx, const unsigned char *key, size_t keylen,
     return gcm_init(vctx, key, keylen, iv, ivlen, 0);
 }
 
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter)
+{
+    int n = 8;
+    unsigned char c;
+
+    do {
+        --n;
+        c = counter[n];
+        ++c;
+        counter[n] = c;
+        if (c > 0)
+            return;
+    } while (n > 0);
+}
+
+static int getivgen(PROV_GCM_CTX *ctx, unsigned char *out, size_t olen)
+{
+    if (!ctx->iv_gen
+        || !ctx->key_set
+        || !ctx->hw->setiv(ctx, ctx->iv, ctx->ivlen))
+        return 0;
+    if (olen == 0 || olen > ctx->ivlen)
+        olen = ctx->ivlen;
+    memcpy(out, ctx->iv + ctx->ivlen - olen, olen);
+    /*
+     * Invocation field will be at least 8 bytes in size and so no need
+     * to check wrap around or increment more than last 8 bytes.
+     */
+    ctr64_inc(ctx->iv + ctx->ivlen - 8);
+    ctx->iv_state = IV_STATE_COPIED;
+    return 1;
+}
+
+static int setivinv(PROV_GCM_CTX *ctx, unsigned char *in, size_t inl)
+{
+    if (!ctx->iv_gen
+        || !ctx->key_set
+        || ctx->enc)
+        return 0;
+
+    memcpy(ctx->iv + ctx->ivlen - inl, in, inl);
+    if (!ctx->hw->setiv(ctx, ctx->iv, ctx->ivlen))
+        return 0;
+    ctx->iv_state = IV_STATE_COPIED;
+    return 1;
+}
+
 int gcm_get_ctx_params(void *vctx, OSSL_PARAM params[])
 {
     PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
@@ -138,7 +186,13 @@ int gcm_get_ctx_params(void *vctx, OSSL_PARAM params[])
             return 0;
         }
     }
-
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN);
+    if (p != NULL) {
+        if (p->data == NULL
+            || p->data_type != OSSL_PARAM_OCTET_STRING
+            || !getivgen(ctx, p->data, p->data_size))
+            return 0;
+    }
     return 1;
 }
 
@@ -201,6 +255,14 @@ int gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[])
             return 0;
         }
     }
+    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV);
+    if (p != NULL) {
+        if (p->data == NULL
+            || p->data_type != OSSL_PARAM_OCTET_STRING
+            || !setivinv(ctx, p->data, p->data_size))
+            return 0;
+    }
+
 
     return 1;
 }
@@ -397,22 +459,6 @@ static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
     return 1;
 }
 
-/* increment counter (64-bit int) by 1 */
-static void ctr64_inc(unsigned char *counter)
-{
-    int n = 8;
-    unsigned char c;
-
-    do {
-        --n;
-        c = counter[n];
-        ++c;
-        counter[n] = c;
-        if (c > 0)
-            return;
-    } while (n > 0);
-}
-
 /*
  * Handle TLS GCM packet format. This consists of the last portion of the IV
  * followed by the payload and finally the tag. On encrypt generate IV,
@@ -445,29 +491,17 @@ static int gcm_tls_cipher(PROV_GCM_CTX *ctx, unsigned char *out, size_t *padlen,
         goto err;
     }
 
-    if (ctx->iv_gen == 0)
-        goto err;
     /*
      * Set IV from start of buffer or generate IV and write to start of
      * buffer.
      */
     if (ctx->enc) {
-        if (!ctx->hw->setiv(ctx, ctx->iv, ctx->ivlen))
+        if (!getivgen(ctx, out, arg))
             goto err;
-        if (arg > ctx->ivlen)
-            arg = ctx->ivlen;
-        memcpy(out, ctx->iv + ctx->ivlen - arg, arg);
-        /*
-         * Invocation field will be at least 8 bytes in size and so no need
-         * to check wrap around or increment more than last 8 bytes.
-         */
-        ctr64_inc(ctx->iv + ctx->ivlen - 8);
     } else {
-        memcpy(ctx->iv + ctx->ivlen - arg, out, arg);
-        if (!ctx->hw->setiv(ctx, ctx->iv, ctx->ivlen))
+        if (!setivinv(ctx, out, arg))
             goto err;
     }
-    ctx->iv_state = IV_STATE_COPIED;
 
     /* Fix buffer and length to point to payload */
     in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
@@ -493,3 +527,4 @@ err:
     *padlen = plen;
     return rv;
 }
+


More information about the openssl-commits mailing list