AEAD support in ssl/
[oweals/openssl.git] / ssl / ssl_ciph.c
index e4bc18440e472dcde3efe4f45bf9fa089ebe2c5e..4eb86fbcfab3146e3077b6c3e12cfaae1003cbaa 100644 (file)
@@ -484,32 +484,72 @@ static void load_builtin_compressions(void)
        }
 #endif
 
+/* ssl_cipher_get_comp sets |comp| to the correct SSL_COMP for the given
+ * session and returns 1. On error it returns 0. */
+int ssl_cipher_get_comp(const SSL_SESSION *s, SSL_COMP **comp)
+       {
+       int i;
+
+       SSL_COMP ctmp;
+#ifndef OPENSSL_NO_COMP
+       load_builtin_compressions();
+#endif
+
+       *comp=NULL;
+       ctmp.id=s->compress_meth;
+       if (ssl_comp_methods != NULL)
+               {
+               i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
+               if (i >= 0)
+                       *comp=sk_SSL_COMP_value(ssl_comp_methods,i);
+               else
+                       *comp=NULL;
+               }
+
+       return 1;
+       }
+
+/* ssl_cipher_get_evp_aead sets |*aead| to point to the correct EVP_AEAD object
+ * for |s->cipher|. It returns 1 on success and 0 on error. */
+int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead)
+       {
+       const SSL_CIPHER *c = s->cipher;
+
+       *aead = NULL;
+
+       if (c == NULL)
+               return 0;
+       if ((c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) == 0)
+               return 0;
+
+       switch (c->algorithm_enc)
+               {
+#ifndef OPENSSL_NO_AES
+       case SSL_AES128GCM:
+               *aead = EVP_aead_aes_128_gcm();
+               return 1;
+       case SSL_AES256GCM:
+               *aead = EVP_aead_aes_256_gcm();
+               return 1;
+#endif
+               }
+
+       return 0;
+       }
+
 int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-            const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp)
+            const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size)
        {
        int i;
        const SSL_CIPHER *c;
 
        c=s->cipher;
        if (c == NULL) return(0);
-       if (comp != NULL)
-               {
-               SSL_COMP ctmp;
-#ifndef OPENSSL_NO_COMP
-               load_builtin_compressions();
-#endif
 
-               *comp=NULL;
-               ctmp.id=s->compress_meth;
-               if (ssl_comp_methods != NULL)
-                       {
-                       i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
-                       if (i >= 0)
-                               *comp=sk_SSL_COMP_value(ssl_comp_methods,i);
-                       else
-                               *comp=NULL;
-                       }
-               }
+       /* This function doesn't deal with EVP_AEAD. See
+        * |ssl_cipher_get_aead_evp|. */
+       if (c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD)
+               return(0);
 
        if ((enc == NULL) || (md == NULL)) return(0);
 
@@ -972,7 +1012,10 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
 #ifdef CIPHER_DEBUG
                        printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
 #endif
-
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+                       if (cipher_id && cipher_id != cp->id)
+                               continue;
+#endif
                        if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
                                continue;
                        if (alg_auth && !(alg_auth & cp->algorithm_auth))
@@ -1347,7 +1390,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
 
        return(retval);
        }
-
+#ifndef OPENSSL_NO_EC
 static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
                                        const char **prule_str)
        {
@@ -1374,7 +1417,18 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
 
        if (!suiteb_flags)
                return 1;
-       /* Check version */
+       /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */
+
+       if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS))
+               {
+               if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)
+                       SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST,
+                               SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);
+               else
+                       SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST,
+                               SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE);
+               return 0;
+               }
 
        switch(suiteb_flags)
                {
@@ -1395,6 +1449,7 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
        c->ecdh_tmp_auto = 1;
        return 1;
        }
+#endif
 
 
 STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
@@ -1414,10 +1469,10 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
         */
        if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
                return NULL;
-
+#ifndef OPENSSL_NO_EC
        if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))
                return NULL;
-
+#endif
 
        /*
         * To reduce the work to do we only want to process the compiled