GMAC implementation
[openssl.git] / crypto / include / internal / evp_int.h
index 0b1c6b2adb17504d0629150ace296a5d12de3e32..98adf1fd2f59f089b05826f6e5db280d1c061a22 100644 (file)
@@ -1,61 +1,21 @@
 /*
- * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
- * 2015.
- */
-/* ====================================================================
- * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
+ * Copyright 2015-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 <openssl/evp.h>
+#include "internal/refcount.h"
+
+/*
+ * Don't free up md_ctx->pctx in EVP_MD_CTX_reset, use the reserved flag
+ * values in evp.h
+ */
+#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX   0x0400
+
 struct evp_pkey_ctx_st {
     /* Method associated with this operation */
     const EVP_PKEY_METHOD *pmeth;
@@ -117,6 +77,16 @@ struct evp_pkey_method_st {
     int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
     int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
     int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);
+    int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
+                       const unsigned char *tbs, size_t tbslen);
+    int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
+                         size_t siglen, const unsigned char *tbs,
+                         size_t tbslen);
+    int (*check) (EVP_PKEY *pkey);
+    int (*public_check) (EVP_PKEY *pkey);
+    int (*param_check) (EVP_PKEY *pkey);
+
+    int (*digest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
 } /* EVP_PKEY_METHOD */ ;
 
 DEFINE_STACK_OF_CONST(EVP_PKEY_METHOD)
@@ -128,10 +98,49 @@ extern const EVP_PKEY_METHOD dh_pkey_meth;
 extern const EVP_PKEY_METHOD dhx_pkey_meth;
 extern const EVP_PKEY_METHOD dsa_pkey_meth;
 extern const EVP_PKEY_METHOD ec_pkey_meth;
+extern const EVP_PKEY_METHOD sm2_pkey_meth;
+extern const EVP_PKEY_METHOD ecx25519_pkey_meth;
+extern const EVP_PKEY_METHOD ecx448_pkey_meth;
+extern const EVP_PKEY_METHOD ed25519_pkey_meth;
+extern const EVP_PKEY_METHOD ed448_pkey_meth;
 extern const EVP_PKEY_METHOD hmac_pkey_meth;
 extern const EVP_PKEY_METHOD rsa_pkey_meth;
+extern const EVP_PKEY_METHOD rsa_pss_pkey_meth;
+extern const EVP_PKEY_METHOD scrypt_pkey_meth;
 extern const EVP_PKEY_METHOD tls1_prf_pkey_meth;
 extern const EVP_PKEY_METHOD hkdf_pkey_meth;
+extern const EVP_PKEY_METHOD poly1305_pkey_meth;
+extern const EVP_PKEY_METHOD siphash_pkey_meth;
+
+/* struct evp_mac_impl_st is defined by the implementation */
+typedef struct evp_mac_impl_st EVP_MAC_IMPL;
+struct evp_mac_st {
+    int type;
+    EVP_MAC_IMPL *(*new) (void);
+    int (*copy) (EVP_MAC_IMPL *macdst, EVP_MAC_IMPL *macsrc);
+    void (*free) (EVP_MAC_IMPL *macctx);
+    size_t (*size) (EVP_MAC_IMPL *macctx);
+    int (*init) (EVP_MAC_IMPL *macctx);
+    int (*update) (EVP_MAC_IMPL *macctx, const unsigned char *data,
+                   size_t datalen);
+    int (*final) (EVP_MAC_IMPL *macctx, unsigned char *out);
+    int (*ctrl) (EVP_MAC_IMPL *macctx, int cmd, va_list args);
+    int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value);
+};
+
+extern const EVP_MAC cmac_meth;
+extern const EVP_MAC gmac_meth;
+extern const EVP_MAC hmac_meth;
+extern const EVP_MAC siphash_meth;
+
+/*
+ * This function is internal for now, but can be made external when needed.
+ * The documentation would read:
+ *
+ * EVP_add_mac() adds the MAC implementation C<mac> to the internal
+ * object database.
+ */
+int EVP_add_mac(const EVP_MAC *mac);
 
 struct evp_md_st {
     int type;
@@ -181,14 +190,15 @@ struct evp_cipher_st {
 
 /* Wrapper functions for each cipher mode */
 
-#define EVP_C_DATA(kstruct, ctx)   ((kstruct *)EVP_CIPHER_CTX_cipher_data(ctx))
+#define EVP_C_DATA(kstruct, ctx) \
+        ((kstruct *)EVP_CIPHER_CTX_get_cipher_data(ctx))
 
 #define BLOCK_CIPHER_ecb_loop() \
         size_t i, bl; \
         bl = EVP_CIPHER_CTX_cipher(ctx)->block_size;    \
-        if(inl < bl) return 1;\
+        if (inl < bl) return 1;\
         inl -= bl; \
-        for(i=0; i <= inl; i+=bl)
+        for (i=0; i <= inl; i+=bl)
 
 #define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
 static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
@@ -237,20 +247,25 @@ static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns
 #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched)  \
 static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
-        size_t chunk=EVP_MAXCHUNK;\
-        if (cbits==1)  chunk>>=3;\
-        if (inl<chunk) chunk=inl;\
-        while(inl && inl>=chunk)\
-            {\
-            int num = EVP_CIPHER_CTX_num(ctx);\
-            cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx)); \
-            EVP_CIPHER_CTX_set_num(ctx, num);\
-            inl-=chunk;\
-            in +=chunk;\
-            out+=chunk;\
-            if(inl<chunk) chunk=inl;\
-            }\
-        return 1;\
+    size_t chunk = EVP_MAXCHUNK;\
+    if (cbits == 1)  chunk >>= 3;\
+    if (inl < chunk) chunk = inl;\
+    while (inl && inl >= chunk)\
+    {\
+        int num = EVP_CIPHER_CTX_num(ctx);\
+        cprefix##_cfb##cbits##_encrypt(in, out, (long) \
+            ((cbits == 1) \
+                && !EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS) \
+                ? chunk*8 : chunk), \
+            &EVP_C_DATA(kstruct, ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx),\
+            &num, EVP_CIPHER_CTX_encrypting(ctx));\
+        EVP_CIPHER_CTX_set_num(ctx, num);\
+        inl -= chunk;\
+        in += chunk;\
+        out += chunk;\
+        if (inl < chunk) chunk = inl;\
+    }\
+    return 1;\
 }
 
 #define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
@@ -388,6 +403,21 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
                              cipher##_init_key, NULL, NULL, NULL, NULL)
 
 
+# ifndef OPENSSL_NO_EC
+
+#define X25519_KEYLEN        32
+#define X448_KEYLEN          56
+#define ED448_KEYLEN         57
+
+#define MAX_KEYLEN  ED448_KEYLEN
+
+typedef struct {
+    unsigned char pubkey[MAX_KEYLEN];
+    unsigned char *privkey;
+} ECX_KEY;
+
+#endif
+
 /*
  * Type needs to be a bit field Sub-type needs to be for variations on the
  * method, as in, can it do arbitrary encryption....
@@ -395,11 +425,12 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
 struct evp_pkey_st {
     int type;
     int save_type;
-    int references;
+    CRYPTO_REF_COUNT references;
     const EVP_PKEY_ASN1_METHOD *ameth;
     ENGINE *engine;
+    ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */
     union {
-        char *ptr;
+        void *ptr;
 # ifndef OPENSSL_NO_RSA
         struct rsa_st *rsa;     /* RSA */
 # endif
@@ -411,12 +442,32 @@ struct evp_pkey_st {
 # endif
 # ifndef OPENSSL_NO_EC
         struct ec_key_st *ec;   /* ECC */
+        ECX_KEY *ecx;           /* X25519, X448, Ed25519, Ed448 */
 # endif
     } pkey;
     int save_parameters;
     STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+    CRYPTO_RWLOCK *lock;
 } /* EVP_PKEY */ ;
 
 
-void openssl_add_all_ciphers_internal(void);
-void openssl_add_all_digests_internal(void);
+void openssl_add_all_ciphers_int(void);
+void openssl_add_all_digests_int(void);
+void openssl_add_all_macs_int(void);
+void evp_cleanup_int(void);
+void evp_app_cleanup_int(void);
+
+/* Pulling defines out of C source files */
+
+#define EVP_RC4_KEY_SIZE 16
+#ifndef TLS1_1_VERSION
+# define TLS1_1_VERSION   0x0302
+#endif
+
+void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags);
+
+/* EVP_ENCODE_CTX flags */
+/* Don't generate new lines when encoding */
+#define EVP_ENCODE_CTX_NO_NEWLINES          1
+/* Use the SRP base64 alphabet instead of the standard one */
+#define EVP_ENCODE_CTX_USE_SRP_ALPHABET     2