GMAC implementation
authorPauli <paul.dale@oracle.com>
Sun, 4 Nov 2018 22:09:41 +0000 (08:09 +1000)
committerPauli <paul.dale@oracle.com>
Sun, 4 Nov 2018 22:09:41 +0000 (08:09 +1000)
Remove GMAC demo program because it has been superceded by the EVP MAC one

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7548)

21 files changed:
CHANGES
Configure
crypto/err/openssl.txt
crypto/evp/c_allm.c
crypto/evp/evp_err.c
crypto/gmac/build.info [new file with mode: 0644]
crypto/gmac/gmac.c [new file with mode: 0644]
crypto/include/internal/evp_int.h
crypto/objects/obj_dat.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt
demos/evp/Makefile
demos/evp/gmac.c [deleted file]
doc/man3/EVP_MAC.pod
doc/man7/EVP_MAC_GMAC.pod [new file with mode: 0644]
fuzz/oids.txt
include/openssl/evp.h
include/openssl/evperr.h
include/openssl/obj_mac.h
test/evp_test.c
test/recipes/30-test_evp_data/evpmac.txt

diff --git a/CHANGES b/CHANGES
index 29be4fc..de10744 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,9 @@
 
  Changes between 1.1.1 and 1.1.2 [xx XXX xxxx]
 
+  *) Add GMAC to EVP_MAC.
+     [Paul Dale]
+
   *) Ported the HMAC, CMAC and SipHash EVP_PKEY_METHODs to EVP_MAC.
      [Richard Levitte]
 
index f46be6b..53d5549 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -308,7 +308,7 @@ $config{sdirs} = [
     "bn", "ec", "rsa", "dsa", "dh", "sm2", "dso", "engine",
     "buffer", "bio", "stack", "lhash", "rand", "err",
     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
-    "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store"
+    "cms", "ts", "srp", "gmac", "cmac", "ct", "async", "kdf", "store"
     ];
 # test/ subdirectories to build
 $config{tdirs} = [ "ossl_shim" ];
index 151bc83..6c52881 100644 (file)
@@ -801,6 +801,7 @@ EVP_F_EVP_PKEY_VERIFY_RECOVER:144:EVP_PKEY_verify_recover
 EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT:145:EVP_PKEY_verify_recover_init
 EVP_F_EVP_SIGNFINAL:107:EVP_SignFinal
 EVP_F_EVP_VERIFYFINAL:108:EVP_VerifyFinal
+EVP_F_GMAC_CTRL:215:gmac_ctrl
 EVP_F_INT_CTX_NEW:157:int_ctx_new
 EVP_F_OK_NEW:200:ok_new
 EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen
@@ -2223,6 +2224,7 @@ EVP_R_ARIA_KEY_SETUP_FAILED:176:aria key setup failed
 EVP_R_BAD_DECRYPT:100:bad decrypt
 EVP_R_BUFFER_TOO_SMALL:155:buffer too small
 EVP_R_CAMELLIA_KEY_SETUP_FAILED:157:camellia key setup failed
+EVP_R_CIPHER_NOT_GCM_MODE:184:cipher not gcm mode
 EVP_R_CIPHER_PARAMETER_ERROR:122:cipher parameter error
 EVP_R_COMMAND_NOT_SUPPORTED:147:command not supported
 EVP_R_COPY_ERROR:173:copy error
index 2bcd9dc..2b9d442 100644 (file)
@@ -15,6 +15,7 @@ void openssl_add_all_macs_int(void)
 #ifndef OPENSSL_NO_CMAC
     EVP_add_mac(&cmac_meth);
 #endif
+    EVP_add_mac(&gmac_meth);
     EVP_add_mac(&hmac_meth);
 #ifndef OPENSSL_NO_SIPHASH
     EVP_add_mac(&siphash_meth);
index 32760db..05d9565 100644 (file)
@@ -141,6 +141,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
      "EVP_PKEY_verify_recover_init"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SIGNFINAL, 0), "EVP_SignFinal"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, 0), "EVP_VerifyFinal"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_GMAC_CTRL, 0), "gmac_ctrl"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_INT_CTX_NEW, 0), "int_ctx_new"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_OK_NEW, 0), "ok_new"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_PBE_KEYIVGEN, 0), "PKCS5_PBE_keyivgen"},
@@ -170,6 +171,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
     "camellia key setup failed"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_NOT_GCM_MODE),
+    "cipher not gcm mode"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR),
     "cipher parameter error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED),
diff --git a/crypto/gmac/build.info b/crypto/gmac/build.info
new file mode 100644 (file)
index 0000000..6d9f22e
--- /dev/null
@@ -0,0 +1,2 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=gmac.c
diff --git a/crypto/gmac/gmac.c b/crypto/gmac/gmac.c
new file mode 100644 (file)
index 0000000..929d9a8
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdlib.h>
+#include <openssl/evp.h>
+#include "internal/cryptlib.h"
+#include "internal/evp_int.h"
+
+/* typedef EVP_MAC_IMPL */
+struct evp_mac_impl_st {
+    EVP_CIPHER *cipher;      /* Cache GCM cipher */
+    EVP_CIPHER_CTX *ctx;    /* Cipher context */
+    ENGINE *engine;         /* Engine implementating the algorithm */
+};
+
+static void gmac_free(EVP_MAC_IMPL *gctx)
+{
+    if (gctx != NULL) {
+        EVP_CIPHER_CTX_free(gctx->ctx);
+        OPENSSL_free(gctx);
+    }
+}
+
+static EVP_MAC_IMPL *gmac_new(void)
+{
+    EVP_MAC_IMPL *gctx;
+
+    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) == NULL
+        || (gctx->ctx = EVP_CIPHER_CTX_new()) == NULL) {
+        gmac_free(gctx);
+        return NULL;
+    }
+    return gctx;
+}
+
+static int gmac_copy(EVP_MAC_IMPL *gdst, EVP_MAC_IMPL *gsrc)
+{
+    gdst->cipher = gsrc->cipher;
+    gdst->engine = gsrc->engine;
+    return EVP_CIPHER_CTX_copy(gdst->ctx, gsrc->ctx);
+}
+
+static size_t gmac_size(EVP_MAC_IMPL *gctx)
+{
+    return EVP_GCM_TLS_TAG_LEN;
+}
+
+static int gmac_init(EVP_MAC_IMPL *gctx)
+{
+    return 1;
+}
+
+static int gmac_update(EVP_MAC_IMPL *gctx, const unsigned char *data,
+                       size_t datalen)
+{
+    EVP_CIPHER_CTX *ctx = gctx->ctx;
+    int outlen;
+
+    while (datalen > INT_MAX) {
+        if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX))
+            return 0;
+        data += INT_MAX;
+        datalen -= INT_MAX;
+    }
+    return EVP_EncryptUpdate(ctx, NULL, &outlen, data, datalen);
+}
+
+static int gmac_final(EVP_MAC_IMPL *gctx, unsigned char *out)
+{
+    int hlen;
+
+    if (!EVP_EncryptFinal_ex(gctx->ctx, out, &hlen)
+        || !EVP_CIPHER_CTX_ctrl(gctx->ctx, EVP_CTRL_AEAD_GET_TAG,
+                                gmac_size(gctx), out))
+        return 0;
+    return 1;
+}
+
+static int gmac_ctrl(EVP_MAC_IMPL *gctx, int cmd, va_list args)
+{
+    const unsigned char *p;
+    size_t len;
+    EVP_CIPHER_CTX *ctx = gctx->ctx;
+    const EVP_CIPHER *cipher;
+    ENGINE *engine;
+
+    switch (cmd) {
+    case EVP_MAC_CTRL_SET_CIPHER:
+        cipher = va_arg(args, const EVP_CIPHER *);
+        if (cipher == NULL)
+            return 0;
+        if (EVP_CIPHER_mode(cipher) != EVP_CIPH_GCM_MODE) {
+            EVPerr(EVP_F_GMAC_CTRL, EVP_R_CIPHER_NOT_GCM_MODE);
+            return 0;
+        }
+        return EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL);
+
+    case EVP_MAC_CTRL_SET_KEY:
+        p = va_arg(args, const unsigned char *);
+        len = va_arg(args, size_t);
+        if (len != (size_t)EVP_CIPHER_CTX_key_length(ctx)) {
+            EVPerr(EVP_F_GMAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        return EVP_EncryptInit_ex(ctx, NULL, NULL, p, NULL);
+
+    case EVP_MAC_CTRL_SET_IV:
+        p = va_arg(args, const unsigned char *);
+        len = va_arg(args, size_t);
+        return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL)
+               && EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, p);
+
+    case EVP_MAC_CTRL_SET_ENGINE:
+        engine = va_arg(args, ENGINE *);
+        return EVP_EncryptInit_ex(ctx, NULL, engine, NULL, NULL);
+
+    default:
+        return -2;
+    }
+}
+
+static int gmac_ctrl_int(EVP_MAC_IMPL *gctx, int cmd, ...)
+{
+    int rv;
+    va_list args;
+
+    va_start(args, cmd);
+    rv = gmac_ctrl(gctx, cmd, args);
+    va_end(args);
+
+    return rv;
+}
+
+static int gmac_ctrl_str_cb(void *gctx, int cmd, void *buf, size_t buflen)
+{
+    return gmac_ctrl_int(gctx, cmd, buf, buflen);
+}
+
+static int gmac_ctrl_str(EVP_MAC_IMPL *gctx, const char *type,
+                         const char *value)
+{
+    if (!value)
+        return 0;
+    if (strcmp(type, "cipher") == 0) {
+        const EVP_CIPHER *c = EVP_get_cipherbyname(value);
+
+        if (c == NULL)
+            return 0;
+        return gmac_ctrl_int(gctx, EVP_MAC_CTRL_SET_CIPHER, c);
+    }
+    if (strcmp(type, "key") == 0)
+        return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY,
+                            value);
+    if (strcmp(type, "hexkey") == 0)
+        return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY,
+                            value);
+    if (strcmp(type, "iv") == 0)
+        return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV,
+                            value);
+    if (strcmp(type, "hexiv") == 0)
+        return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV,
+                            value);
+    return -2;
+}
+
+const EVP_MAC gmac_meth = {
+    EVP_MAC_GMAC,
+    gmac_new,
+    gmac_copy,
+    gmac_free,
+    gmac_size,
+    gmac_init,
+    gmac_update,
+    gmac_final,
+    gmac_ctrl,
+    gmac_ctrl_str
+};
index 060538e..98adf1f 100644 (file)
@@ -129,6 +129,7 @@ struct evp_mac_st {
 };
 
 extern const EVP_MAC cmac_meth;
+extern const EVP_MAC gmac_meth;
 extern const EVP_MAC hmac_meth;
 extern const EVP_MAC siphash_meth;
 
index e931f7f..d9365ce 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /* Serialized OID's */
-static const unsigned char so[7762] = {
+static const unsigned char so[7767] = {
     0x2A,0x86,0x48,0x86,0xF7,0x0D,                 /* [    0] OBJ_rsadsi */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,            /* [    6] OBJ_pkcs */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,       /* [   13] OBJ_md2 */
@@ -1076,9 +1076,10 @@ static const unsigned char so[7762] = {
     0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04,  /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C,       /* [ 7745] OBJ_hmacWithSHA512_224 */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D,       /* [ 7753] OBJ_hmacWithSHA512_256 */
+    0x28,0xCC,0x45,0x03,0x04,                      /* [ 7761] OBJ_gmac */
 };
 
-#define NUM_NID 1195
+#define NUM_NID 1196
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2275,9 +2276,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"magma-mac", "magma-mac", NID_magma_mac},
     {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]},
     {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]},
+    {"GMAC", "gmac", NID_gmac, 5, &so[7761]},
 };
 
-#define NUM_SN 1186
+#define NUM_SN 1187
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
@@ -2424,6 +2426,7 @@ static const unsigned int sn_objs[NUM_SN] = {
      297,    /* "DVCS" */
     1087,    /* "ED25519" */
     1088,    /* "ED448" */
+    1195,    /* "GMAC" */
       99,    /* "GN" */
     1036,    /* "HKDF" */
      855,    /* "HMAC" */
@@ -3467,7 +3470,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1093,    /* "x509ExtAdmission" */
 };
 
-#define NUM_LN 1186
+#define NUM_LN 1187
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
@@ -3961,6 +3964,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      509,    /* "generationQualifier" */
      601,    /* "generic cryptogram" */
       99,    /* "givenName" */
+    1195,    /* "gmac" */
      976,    /* "gost-mac-12" */
     1009,    /* "gost89-cbc" */
      814,    /* "gost89-cnt" */
@@ -4657,7 +4661,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      125,    /* "zlib compression" */
 };
 
-#define NUM_OBJ 1071
+#define NUM_OBJ 1072
 static const unsigned int obj_objs[NUM_OBJ] = {
        0,    /* OBJ_undef                        0 */
      181,    /* OBJ_iso                          1 */
@@ -4904,6 +4908,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
      637,    /* OBJ_set_brand_Diners             2 23 42 8 30 */
      638,    /* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
      639,    /* OBJ_set_brand_JCB                2 23 42 8 35 */
+    1195,    /* OBJ_gmac                         1 0 9797 3 4 */
     1141,    /* OBJ_oscca                        1 2 156 10197 */
      805,    /* OBJ_cryptopro                    1 2 643 2 2 */
      806,    /* OBJ_cryptocom                    1 2 643 2 9 */
index 1b6a9c6..487eeff 100644 (file)
@@ -1192,3 +1192,4 @@ magma_cfb         1191
 magma_mac              1192
 hmacWithSHA512_224             1193
 hmacWithSHA512_256             1194
+gmac           1195
index 6dbc41c..1e83dff 100644 (file)
@@ -11,6 +11,9 @@ iso 2                 : member-body           : ISO Member Body
 
 iso 3                  : identified-organization
 
+# GMAC OID
+iso 0 9797 3 4                          : GMAC          : gmac
 # HMAC OIDs
 identified-organization 6 1 5 5 8 1 1  : HMAC-MD5      : hmac-md5
 identified-organization 6 1 5 5 8 1 2  : HMAC-SHA1     : hmac-sha1
index 1fb0f39..c2e10a1 100644 (file)
@@ -7,19 +7,17 @@
 #
 #    LD_LIBRARY_PATH=../.. ./aesccm
 #    LD_LIBRARY_PATH=../.. ./aesgcm
-#    LD_LIBRARY_PATH=../.. ./gmac
 
 CFLAGS = $(OPENSSL_INCS_LOCATION)
 LDFLAGS = $(OPENSSL_LIBS_LOCATION) -lssl -lcrypto
 
-all: aesccm aesgcm gmac
+all: aesccm aesgcm
 
 aesccm: aesccm.o
 aesgcm: aesgcm.o
-gmac: gmac.o
 
-aesccm aesgcm gmac:
+aesccm aesgcm:
        $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
 
 clean:
-       $(RM) aesccm aesgcm gmac *.o
+       $(RM) aesccm aesgcm *.o
diff --git a/demos/evp/gmac.c b/demos/evp/gmac.c
deleted file mode 100644 (file)
index 0b2231b..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * Simple AES GMAC test program, uses the same NIST data used for the FIPS
- * self test but uses the application level EVP APIs.
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-
-/* AES-GMAC test data from NIST public test vectors */
-
-static const unsigned char gmac_key[] = { 0x77, 0xbe, 0x63, 0x70, 0x89, 0x71, 0xc4, 0xe2,
-               0x40, 0xd1, 0xcb, 0x79, 0xe8, 0xd7, 0x7f, 0xeb };
-static const unsigned char gmac_iv[] = { 0xe0, 0xe0, 0x0f, 0x19, 0xfe, 0xd7, 0xba, 0x01,
-              0x36, 0xa7, 0x97, 0xf3 };
-static const unsigned char gmac_aad[] = { 0x7a, 0x43, 0xec, 0x1d, 0x9c, 0x0a, 0x5a, 0x78,
-               0xa0, 0xb1, 0x65, 0x33, 0xa6, 0x21, 0x3c, 0xab };
-
-static const unsigned char gmac_tag[] = { 0x20, 0x9f, 0xcc, 0x8d, 0x36, 0x75, 0xed, 0x93,
-               0x8e, 0x9c, 0x71, 0x66, 0x70, 0x9d, 0xd9, 0x46 };
-
-static int aes_gmac(void)
-{
-    EVP_CIPHER_CTX *ctx;
-    int outlen, tmplen;
-    unsigned char outbuf[1024];
-    int ret = 0;
-
-    printf("AES GMAC:\n");
-    printf("Authenticated Data:\n");
-    BIO_dump_fp(stdout, gmac_aad, sizeof(gmac_aad));
-
-    if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
-        printf("EVP_CIPHER_CTX_new: failed\n");
-        goto err;
-    }
-
-    /* Set cipher type and mode */
-    if (!EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL)) {
-        printf("EVP_EncryptInit_ex: failed\n");
-        goto err;
-    }
-
-    /* Set IV length if default 96 bits is not appropriate */
-    if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gmac_iv),
-                             NULL)) {
-        printf("EVP_CIPHER_CTX_ctrl: set IV length failed\n");
-        goto err;
-    }
-
-    /* Initialise key and IV */
-    if (!EVP_EncryptInit_ex(ctx, NULL, NULL, gmac_key, gmac_iv)) {
-        printf("EVP_EncryptInit_ex: set key and IV failed\n");
-        goto err;
-    }
-
-    /* Zero or more calls to specify any AAD */
-    if (!EVP_EncryptUpdate(ctx, NULL, &outlen, gmac_aad, sizeof(gmac_aad))) {
-        printf("EVP_EncryptUpdate: setting AAD failed\n");
-        goto err;
-    }
-
-    /* Finalise: note get no output for GMAC */
-    if (!EVP_EncryptFinal_ex(ctx, outbuf, &outlen)) {
-        printf("EVP_EncryptFinal_ex: failed\n");
-        goto err;
-    }
-
-    /* Get tag */
-    if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf)) {
-        printf("EVP_CIPHER_CTX_ctrl: failed\n");
-        goto err;
-    }
-
-    /* Output tag */
-    printf("Tag:\n");
-    BIO_dump_fp(stdout, outbuf, 16);
-
-    /* Is the tag correct? */
-    if (memcmp(outbuf, gmac_tag, sizeof(gmac_tag)) != 0) {
-        printf("Expected:\n");
-        BIO_dump_fp(stdout, gmac_tag, sizeof(gmac_tag));
-    } else 
-        ret = 1;
-err:
-    EVP_CIPHER_CTX_free(ctx);
-    return ret;
-}
-
-int main(int argc, char **argv)
-{
-    return aes_gmac() ? EXIT_SUCCESS : EXIT_FAILURE;
-}
index a320181..473d6c9 100644 (file)
@@ -163,6 +163,12 @@ For MACs that use an underlying computation algorithm, the algorithm
 I<must> be set first, see B<EVP_MAC_CTRL_SET_ENGINE>,
 B<EVP_MAC_CTRL_SET_MD> and B<EVP_MAC_CTRL_SET_CIPHER> below.
 
+=item B<EVP_MAC_CTRL_SET_IV>
+
+This control expects two arguments: C<unsigned char *key>, C<size_t keylen>
+
+Some MAC implementations require an IV, this control sets the IV.
+
 =item B<EVP_MAC_CTRL_SET_FLAGS>
 
 This control expects one arguments: C<unsigned long flags>
@@ -327,6 +333,7 @@ F<./foo>)
 =head1 SEE ALSO
 
 L<EVP_MAC_CMAC(7)>,
+L<EVP_MAC_GMAC(7)>,
 L<EVP_MAC_HMAC(7)>,
 L<EVP_MAC_SIPHASH(7)>
 
diff --git a/doc/man7/EVP_MAC_GMAC.pod b/doc/man7/EVP_MAC_GMAC.pod
new file mode 100644 (file)
index 0000000..c35d781
--- /dev/null
@@ -0,0 +1,83 @@
+=pod
+
+=head1 NAME
+
+EVP_MAC_GMAC - The GMAC EVP_MAC implementation
+
+=head1 DESCRIPTION
+
+Support for computing GMAC MACs through the B<EVP_MAC> API.
+
+=head2 Numeric identity
+
+B<EVP_MAC_GMAC> is the numeric identity for this implementation, and
+can be used in functions like EVP_MAC_CTX_new_id() and
+EVP_get_macbynid().
+
+=head2 Supported controls
+
+The supported controls are:
+
+=over 4
+
+=item B<EVP_MAC_CTRL_SET_KEY>
+
+EVP_MAC_ctrl_str() takes two type strings for this control:
+
+=over 4
+
+=item "key"
+
+The value string is used as is.
+
+=item "hexkey"
+
+The value string is expected to be a hexadecimal number, which will be
+decoded before passing on as control value.
+
+=back
+
+=item B<EVP_MAC_CTRL_SET_IV>
+
+EVP_MAC_ctrl_str() takes two type strings for this control:
+
+=over 4
+
+=item "iv"
+
+The value string is used as is.
+
+=item "hexiv"
+
+The value string is expected to be a hexadecimal number, which will be
+decoded before passing on as control value.
+
+=back
+
+=item B<EVP_MAC_CTRL_SET_ENGINE>
+
+=item B<EVP_MAC_CTRL_SET_CIPHER>
+
+These work as described in L<EVP_MAC(3)/CONTROLS> with the restriction that the
+cipher must be an AEAD one.
+
+EVP_MAC_ctrl_str() type string for B<EVP_MAC_CTRL_SET_CIPHER>: "cipher"
+
+The value is expected to be the name of a cipher.
+
+=back
+
+=head1 SEE ALSO
+
+L<EVP_MAC_ctrl(3)>, L<EVP_MAC(3)/CONTROLS>
+
+=head1 COPYRIGHT
+
+Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the OpenSSL license (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index fe363fd..79a68fc 100644 (file)
@@ -1063,3 +1063,4 @@ OBJ_id_tc26_gost_3410_2012_256_paramSetC="\x2A\x85\x03\x07\x01\x02\x01\x01\x03"
 OBJ_id_tc26_gost_3410_2012_256_paramSetD="\x2A\x85\x03\x07\x01\x02\x01\x01\x04"
 OBJ_hmacWithSHA512_224="\x2A\x86\x48\x86\xF7\x0D\x02\x0C"
 OBJ_hmacWithSHA512_256="\x2A\x86\x48\x86\xF7\x0D\x02\x0D"
+OBJ_gmac="\x28\xCC\x45\x03\x04"
index cfd6369..79845aa 100644 (file)
@@ -988,6 +988,7 @@ void EVP_MD_do_all_sorted(void (*fn)
 /* MAC stuff */
 
 # define EVP_MAC_CMAC           NID_cmac
+# define EVP_MAC_GMAC           NID_gmac
 # define EVP_MAC_HMAC           NID_hmac
 # define EVP_MAC_SIPHASH        NID_siphash
 
@@ -1024,6 +1025,7 @@ void EVP_MAC_do_all_sorted(void (*fn)
 # define EVP_MAC_CTRL_SET_MD            0x04 /* EVP_MD * */
 # define EVP_MAC_CTRL_SET_CIPHER        0x04 /* EVP_CIPHER * */
 # define EVP_MAC_CTRL_SET_SIZE          0x05 /* size_t */
+# define EVP_MAC_CTRL_SET_IV            0x06 /* unsigned char *, size_t */
 
 /* PKEY stuff */
 int EVP_PKEY_decrypt_old(unsigned char *dec_key,
index a17e159..17b8187 100644 (file)
@@ -111,6 +111,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT               145
 # define EVP_F_EVP_SIGNFINAL                              107
 # define EVP_F_EVP_VERIFYFINAL                            108
+# define EVP_F_GMAC_CTRL                                  215
 # define EVP_F_INT_CTX_NEW                                157
 # define EVP_F_OK_NEW                                     200
 # define EVP_F_PKCS5_PBE_KEYIVGEN                         117
@@ -133,6 +134,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_R_BAD_DECRYPT                                100
 # define EVP_R_BUFFER_TOO_SMALL                           155
 # define EVP_R_CAMELLIA_KEY_SETUP_FAILED                  157
+# define EVP_R_CIPHER_NOT_GCM_MODE                        184
 # define EVP_R_CIPHER_PARAMETER_ERROR                     122
 # define EVP_R_COMMAND_NOT_SUPPORTED                      147
 # define EVP_R_COPY_ERROR                                 173
index 80ff5a7..0a3e4c5 100644 (file)
 #define NID_identified_organization             676
 #define OBJ_identified_organization             OBJ_iso,3L
 
+#define SN_gmac         "GMAC"
+#define LN_gmac         "gmac"
+#define NID_gmac                1195
+#define OBJ_gmac                OBJ_iso,0L,9797L,3L,4L
+
 #define SN_hmac_md5             "HMAC-MD5"
 #define LN_hmac_md5             "hmac-md5"
 #define NID_hmac_md5            780
index 25b10d3..18b20af 100644 (file)
@@ -838,6 +838,9 @@ typedef struct mac_data_st {
     /* MAC key */
     unsigned char *key;
     size_t key_len;
+    /* MAC IV (GMAC) */
+    unsigned char *iv;
+    size_t iv_len;
     /* Input to MAC */
     unsigned char *input;
     size_t input_len;
@@ -925,6 +928,7 @@ static void mac_test_cleanup(EVP_TEST *t)
     sk_OPENSSL_STRING_pop_free(mdat->controls, openssl_free);
     OPENSSL_free(mdat->alg);
     OPENSSL_free(mdat->key);
+    OPENSSL_free(mdat->iv);
     OPENSSL_free(mdat->input);
     OPENSSL_free(mdat->output);
 }
@@ -936,6 +940,8 @@ static int mac_test_parse(EVP_TEST *t,
 
     if (strcmp(keyword, "Key") == 0)
         return parse_bin(value, &mdata->key, &mdata->key_len);
+    if (strcmp(keyword, "IV") == 0)
+        return parse_bin(value, &mdata->iv, &mdata->iv_len);
     if (strcmp(keyword, "Algorithm") == 0) {
         mdata->alg = OPENSSL_strdup(value);
         if (!mdata->alg)
@@ -1119,6 +1125,18 @@ static int mac_test_run_mac(EVP_TEST *t)
         goto err;
     }
 
+    if (expected->iv != NULL) {
+        rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_IV,
+                          expected->iv, expected->iv_len);
+        if (rv == -2) {
+            t->err = "MAC_CTRL_INVALID";
+            goto err;
+        } else if (rv <= 0) {
+            t->err = "MAC_CTRL_ERROR";
+            goto err;
+        }
+    }
+
     if (!EVP_MAC_init(ctx)) {
         t->err = "MAC_INIT_ERROR";
         goto err;
index 4788626..82a3507 100644 (file)
@@ -386,6 +386,75 @@ Key = 89BCD952A8C8AB371AF48AC7D07085D5EFF702E6D62CDC23
 Input = FA620C1BBE97319E9A0CF0492121F7A20EB08A6A709DCBD00AAF38E4F99E754E
 Output = 8F49A1B7D6AA2258
 
+
+Title = GMAC Tests (from NIST)
+
+MAC = GMAC
+Algorithm = AES-128-GCM
+Key = 77BE63708971C4E240D1CB79E8D77FEB
+IV = E0E00F19FED7BA0136A797F3
+Input = 7A43EC1D9C0A5A78A0B16533A6213CAB
+Output = 209FCC8D3675ED938E9C7166709DD946
+
+Title = GMAC Tests (from http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf)
+
+MAC = GMAC
+Algorithm = AES-128-GCM
+Key = AD7A2BD03EAC835A6F620FDCB506B345
+IV = 12153524C0895E81B2C28465
+Input = D609B1F056637A0D46DF998D88E5222AB2C2846512153524C0895E8108000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233340001
+Output = F09478A9B09007D06F46E9B6A1DA25DD
+
+MAC = GMAC
+Algorithm = AES-256-GCM
+Key = E3C08A8F06C6E3AD95A70557B23F75483CE33021A9C72B7025666204C69C0B72
+IV = 12153524C0895E81B2C28465
+Input = D609B1F056637A0D46DF998D88E5222AB2C2846512153524C0895E8108000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233340001
+Output = 2F0BC5AF409E06D609EA8B7D0FA5EA50
+
+MAC = GMAC
+Algorithm = AES-128-GCM
+Key = 071B113B0CA743FECCCF3D051F737382
+IV = F0761E8DCD3D000176D457ED
+Input = E20106D7CD0DF0761E8DCD3D88E5400076D457ED08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0003
+Output = 0C017BC73B227DFCC9BAFA1C41ACC353
+
+MAC = GMAC
+Algorithm = AES-256-GCM
+Key = 691D3EE909D7F54167FD1CA0B5D769081F2BDE1AEE655FDBAB80BD5295AE6BE7
+IV = F0761E8DCD3D000176D457ED
+Input = E20106D7CD0DF0761E8DCD3D88E5400076D457ED08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0003
+Output = 35217C774BBC31B63166BCF9D4ABED07
+
+MAC = GMAC
+Algorithm = AES-128-GCM
+Key = 013FE00B5F11BE7F866D0CBBC55A7A90
+IV = 7CFDE9F9E33724C68932D612
+Input = 84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005
+Output = 217867E50C2DAD74C28C3B50ABDF695A
+
+MAC = GMAC
+Algorithm = AES-256-GCM
+Key = 83C093B58DE7FFE1C0DA926AC43FB3609AC1C80FEE1B624497EF942E2F79A823
+IV = 7CFDE9F9E33724C68932D612
+Input = 84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005
+Output = 6EE160E8FAECA4B36C86B234920CA975
+
+MAC = GMAC
+Algorithm = AES-128-GCM
+Key = 88EE087FD95DA9FBF6725AA9D757B0CD
+IV = 7AE8E2CA4EC500012E58495C
+Input = 68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007
+Output = 07922B8EBCF10BB2297588CA4C614523
+
+MAC = GMAC
+Algorithm = AES-256-GCM
+Key = 4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5
+IV = 7AE8E2CA4EC500012E58495C
+Input = 68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007
+Output = 00BDA1B7E87608BCBF470F12157F4C07
+
+
 Title = Poly1305 Tests (from RFC 7539 and others)
 
 MAC = Poly1305