[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