Backport GCM support from HEAD.
authorDr. Stephen Henson <steve@openssl.org>
Thu, 4 Aug 2011 11:13:28 +0000 (11:13 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 4 Aug 2011 11:13:28 +0000 (11:13 +0000)
CHANGES
ssl/s3_lib.c
ssl/s3_pkt.c
ssl/ssl.h
ssl/ssl_ciph.c
ssl/ssl_locl.h
ssl/t1_enc.c
ssl/tls1.h

diff --git a/CHANGES b/CHANGES
index bd97fedda929d7c1980e23c846348d851c3761f8..d2a10b01a9be53a9c5aad660bb1cdb5170877f8f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,17 @@
 
  Changes between 1.0.0e and 1.0.1  [xx XXX xxxx]
 
+  *) Add GCM support to TLS library. Some custom code is needed to split
+     the IV between the fixed (from PRF) and explicit (from TLS record)
+     portions. This adds all GCM ciphersuites supported by RFC5288 and 
+     RFC5289. Generalise some AES* cipherstrings to inlclude GCM and
+     add a special AESGCM string for GCM only.
+     [Steve Henson]
+
+  *) Expand range of ctrls for AES GCM. Permit setting invocation
+     field on decrypt and retrieval of invocation field only on encrypt.
+     [Steve Henson]
+
   *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support.
      As required by RFC5289 these ciphersuites cannot be used if for
      versions of TLS earlier than 1.2.
index 9b4703686e67666456e8402916005a1dfb4f9cfa..9b4d060c5fe1b0e12b67282e676c735b436a9a08 100644 (file)
@@ -1823,6 +1823,200 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 
 #endif /* OPENSSL_NO_SEED */
 
+       /* GCM ciphersuites from RFC5288 */
+
+       /* Cipher 9C */
+       {
+       1,
+       TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
+       SSL_kRSA,
+       SSL_aRSA,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher 9D */
+       {
+       1,
+       TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
+       SSL_kRSA,
+       SSL_aRSA,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher 9E */
+       {
+       1,
+       TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
+       SSL_kEDH,
+       SSL_aRSA,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher 9F */
+       {
+       1,
+       TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
+       SSL_kEDH,
+       SSL_aRSA,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher A0 */
+       {
+       0,
+       TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256,
+       SSL_kDHr,
+       SSL_aDH,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher A1 */
+       {
+       0,
+       TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384,
+       SSL_kDHr,
+       SSL_aDH,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher A2 */
+       {
+       1,
+       TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256,
+       SSL_kEDH,
+       SSL_aDSS,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher A3 */
+       {
+       1,
+       TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384,
+       SSL_kEDH,
+       SSL_aDSS,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher A4 */
+       {
+       0,
+       TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256,
+       SSL_kDHr,
+       SSL_aDH,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher A5 */
+       {
+       0,
+       TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384,
+       SSL_kDHr,
+       SSL_aDH,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher A6 */
+       {
+       1,
+       TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_ADH_WITH_AES_128_GCM_SHA256,
+       SSL_kEDH,
+       SSL_aNULL,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher A7 */
+       {
+       1,
+       TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_ADH_WITH_AES_256_GCM_SHA384,
+       SSL_kEDH,
+       SSL_aNULL,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
 #ifndef OPENSSL_NO_ECDH
        /* Cipher C001 */
        {
@@ -2502,6 +2696,136 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        256,
        },
 
+       /* GCM based TLS v1.2 ciphersuites from RFC5289 */
+
+       /* Cipher C02B */
+       {
+       1,
+       TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+       SSL_kEECDH,
+       SSL_aECDSA,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher C02C */
+       {
+       1,
+       TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+       SSL_kEECDH,
+       SSL_aECDSA,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher C02D */
+       {
+       1,
+       TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+       SSL_kECDHe,
+       SSL_aECDH,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher C02E */
+       {
+       1,
+       TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+       SSL_kECDHe,
+       SSL_aECDH,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher C02F */
+       {
+       1,
+       TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+       SSL_kEECDH,
+       SSL_aRSA,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher C030 */
+       {
+       1,
+       TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+       SSL_kEECDH,
+       SSL_aRSA,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
+       /* Cipher C031 */
+       {
+       1,
+       TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+       TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+       SSL_kECDHe,
+       SSL_aECDH,
+       SSL_AES128GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+       128,
+       128,
+       },
+
+       /* Cipher C032 */
+       {
+       1,
+       TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+       TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+       SSL_kECDHe,
+       SSL_aECDH,
+       SSL_AES256GCM,
+       SSL_AEAD,
+       SSL_TLSV1_2,
+       SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+       SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+       256,
+       256,
+       },
+
 #endif /* OPENSSL_NO_ECDH */
 
 
index 46304766a4e65ab5be06c2e4fd603c53532db9fb..63536754ce0637605a22053b6b6400d6e5291a37 100644 (file)
@@ -742,12 +742,18 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        plen=p; 
        p+=2;
        /* Explicit IV length, block ciphers and TLS version 1.1 or later */
-       if (s->enc_write_ctx && s->version >= TLS1_1_VERSION
-               && EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)
+       if (s->enc_write_ctx && s->version >= TLS1_1_VERSION)
                {
-               eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
-               if (eivlen <= 1)
-                       eivlen = 0;
+               int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+               if (mode == EVP_CIPH_CBC_MODE)
+                       {
+                       eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+                       if (eivlen <= 1)
+                               eivlen = 0;
+                       }
+               /* Need explicit part of IV for GCM mode */
+               else if (mode == EVP_CIPH_GCM_MODE)
+                       eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
                }
        else 
                eivlen = 0;
index 6af291ba8338cd4d1d18f4c7a2cd36b7bf9dacee..11ed467452e9bebeb413bc2458fe324e683af10e 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -287,6 +287,7 @@ extern "C" {
 #define SSL_TXT_AES128         "AES128"
 #define SSL_TXT_AES256         "AES256"
 #define SSL_TXT_AES            "AES"
+#define SSL_TXT_AES_GCM                "AESGCM"
 #define SSL_TXT_CAMELLIA128    "CAMELLIA128"
 #define SSL_TXT_CAMELLIA256    "CAMELLIA256"
 #define SSL_TXT_CAMELLIA       "CAMELLIA"
index 224c63db775032402855686ba1195ff318981294..29d8f2849d1380fce8f4a2376f25cea3fcc692f0 100644 (file)
 #define SSL_ENC_CAMELLIA256_IDX        9
 #define SSL_ENC_GOST89_IDX     10
 #define SSL_ENC_SEED_IDX       11
-#define SSL_ENC_NUM_IDX                12
+#define SSL_ENC_AES128GCM_IDX  12
+#define SSL_ENC_AES256GCM_IDX  13
+#define SSL_ENC_NUM_IDX                14
 
 
 static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
-       NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+       NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
        };
 
 #define SSL_COMP_NULL_IDX      0
@@ -289,9 +291,10 @@ static const SSL_CIPHER cipher_aliases[]={
        {0,SSL_TXT_IDEA,0,    0,0,SSL_IDEA,  0,0,0,0,0,0},
        {0,SSL_TXT_SEED,0,    0,0,SSL_SEED,  0,0,0,0,0,0},
        {0,SSL_TXT_eNULL,0,   0,0,SSL_eNULL, 0,0,0,0,0,0},
-       {0,SSL_TXT_AES128,0,  0,0,SSL_AES128,0,0,0,0,0,0},
-       {0,SSL_TXT_AES256,0,  0,0,SSL_AES256,0,0,0,0,0,0},
-       {0,SSL_TXT_AES,0,     0,0,SSL_AES128|SSL_AES256,0,0,0,0,0,0},
+       {0,SSL_TXT_AES128,0,  0,0,SSL_AES128|SSL_AES128GCM,0,0,0,0,0,0},
+       {0,SSL_TXT_AES256,0,  0,0,SSL_AES256|SSL_AES256GCM,0,0,0,0,0,0},
+       {0,SSL_TXT_AES,0,     0,0,SSL_AES,0,0,0,0,0,0},
+       {0,SSL_TXT_AES_GCM,0, 0,0,SSL_AES128GCM|SSL_AES256GCM,0,0,0,0,0,0},
        {0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0},
        {0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0},
        {0,SSL_TXT_CAMELLIA   ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0},
@@ -387,6 +390,11 @@ void ssl_load_ciphers(void)
        ssl_cipher_methods[SSL_ENC_SEED_IDX]=
          EVP_get_cipherbyname(SN_seed_cbc);
 
+       ssl_cipher_methods[SSL_ENC_AES128GCM_IDX]=
+         EVP_get_cipherbyname(SN_aes_128_gcm);
+       ssl_cipher_methods[SSL_ENC_AES256GCM_IDX]=
+         EVP_get_cipherbyname(SN_aes_256_gcm);
+
        ssl_digest_methods[SSL_MD_MD5_IDX]=
                EVP_get_digestbyname(SN_md5);
        ssl_mac_secret_size[SSL_MD_MD5_IDX]=
@@ -541,6 +549,12 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
        case SSL_SEED:
                i=SSL_ENC_SEED_IDX;
                break;
+       case SSL_AES128GCM:
+               i=SSL_ENC_AES128GCM_IDX;
+               break;
+       case SSL_AES256GCM:
+               i=SSL_ENC_AES256GCM_IDX;
+               break;
        default:
                i= -1;
                break;
@@ -585,14 +599,15 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
                *md=NULL; 
                if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
                if (mac_secret_size!=NULL) *mac_secret_size = 0;
-
+               if (c->algorithm_mac == SSL_AEAD)
+                       mac_pkey_type = NULL;
        }
        else
        {
                *md=ssl_digest_methods[i];
                if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
                if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
-       }       
+       }
 
        if ((*enc != NULL) &&
            (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) &&
@@ -1635,6 +1650,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
        case SSL_AES256:
                enc="AES(256)";
                break;
+       case SSL_AES128GCM:
+               enc="AESGCM(128)";
+               break;
+       case SSL_AES256GCM:
+               enc="AESGCM(256)";
+               break;
        case SSL_CAMELLIA128:
                enc="Camellia(128)";
                break;
@@ -1663,6 +1684,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
        case SSL_SHA384:
                mac="SHA384";
                break;
+       case SSL_AEAD:
+               mac="AEAD";
+               break;
        default:
                mac="unknown";
                break;
index 983ddaf60924098655ca82ab42e7d9a4e1cbb1b3..65b24dcdf2852bf5a35edadea19fe721d7d25665 100644 (file)
 #define SSL_CAMELLIA256                0x00000200L
 #define SSL_eGOST2814789CNT    0x00000400L
 #define SSL_SEED               0x00000800L
+#define SSL_AES128GCM          0x00001000L
+#define SSL_AES256GCM          0x00002000L
 
-#define SSL_AES                        (SSL_AES128|SSL_AES256)
+#define SSL_AES                        (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
 #define SSL_CAMELLIA           (SSL_CAMELLIA128|SSL_CAMELLIA256)
 
 
 /* Bits for algorithm_mac (symmetric authentication) */
+
 #define SSL_MD5                        0x00000001L
 #define SSL_SHA1               0x00000002L
 #define SSL_GOST94      0x00000004L
 #define SSL_GOST89MAC   0x00000008L
 #define SSL_SHA256             0x00000010L
 #define SSL_SHA384             0x00000020L
+/* Not a real MAC, just an indication it is part of cipher */
+#define SSL_AEAD               0x00000040L
 
 /* Bits for algorithm_ssl (protocol version) */
 #define SSL_SSLV2              0x00000001L
index 1c14637072ebf13b16e8ee56287f09f182a2342a..3452b25c456f0ee33235c3833e2ee6ae8bce6b72 100644 (file)
@@ -456,7 +456,11 @@ int tls1_change_cipher_state(SSL *s, int which)
        j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
                       cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
        /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
-       k=EVP_CIPHER_iv_length(c);
+       /* If GCM mode only part of IV comes from PRF */
+       if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+               k = EVP_GCM_TLS_FIXED_IV_LEN;
+       else
+               k=EVP_CIPHER_iv_length(c);
        if (    (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
                (which == SSL3_CHANGE_CIPHER_SERVER_READ))
                {
@@ -539,7 +543,13 @@ printf("which = %04X\nmac key=",which);
        }
 #endif /* KSSL_DEBUG */
 
-       EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
+       if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+               {
+               EVP_CipherInit_ex(dd,c,NULL,key,NULL,(which & SSL3_CC_WRITE));
+               EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv);
+               }
+       else    
+               EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
 
        /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
        if ((EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size)
@@ -815,8 +825,14 @@ int tls1_enc(SSL *s, int send)
                                }
                        }
                
-               if (!EVP_Cipher(ds,rec->data,rec->input,l))
+               if (EVP_Cipher(ds,rec->data,rec->input,l) < 0)
                        return -1;      /* AEAD can fail to verify MAC */
+               if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send)
+                       {
+                       rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+                       rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+                       rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+                       }
 
 #ifdef KSSL_DEBUG
                {
index e7e82601f5a66494690c4352f432f2c666cf81a7..ef5d5ef357375c86e59bf120ea2f0c0c7bd8f0e4 100644 (file)
@@ -394,6 +394,20 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 #define TLS1_CK_DHE_RSA_WITH_SEED_SHA                   0x0300009A
 #define TLS1_CK_ADH_WITH_SEED_SHA                      0x0300009B
 
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+#define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256            0x0300009C
+#define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384            0x0300009D
+#define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256                0x0300009E
+#define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384                0x0300009F
+#define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256         0x030000A0
+#define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384         0x030000A1
+#define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256                0x030000A2
+#define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384                0x030000A3
+#define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256         0x030000A4
+#define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384         0x030000A5
+#define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256            0x030000A6
+#define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384            0x030000A7
+
 /* ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in draft 13 */
 #define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
 #define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
@@ -447,6 +461,16 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 #define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256            0x0300C029
 #define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384            0x0300C02A
 
+/* ECDH GCM based ciphersuites from RFC5289 */
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256    0x0300C02B
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384    0x0300C02C
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256      0x0300C02D
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384      0x0300C02E
+#define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256       0x0300C02F
+#define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384       0x0300C030
+#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256        0x0300C031
+#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384        0x0300C032
+
 /* XXX
  * Inconsistency alert:
  * The OpenSSL names of ciphers with ephemeral DH here include the string
@@ -563,6 +587,20 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 #define TLS1_TXT_ADH_WITH_AES_128_SHA256               "ADH-AES128-SHA256"
 #define TLS1_TXT_ADH_WITH_AES_256_SHA256               "ADH-AES256-SHA256"
 
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+#define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256           "AES128-GCM-SHA256"
+#define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384           "AES256-GCM-SHA384"
+#define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256       "DHE-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384       "DHE-RSA-AES256-GCM-SHA384"
+#define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256                "DH-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384                "DH-RSA-AES256-GCM-SHA384"
+#define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256       "DHE-DSS-AES128-GCM-SHA256"
+#define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384       "DHE-DSS-AES256-GCM-SHA384"
+#define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256                "DH-DSS-AES128-GCM-SHA256"
+#define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384                "DH-DSS-AES256-GCM-SHA384"
+#define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256           "ADH-AES128-GCM-SHA256"
+#define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384           "ADH-AES256-GCM-SHA384"
+
 /* ECDH HMAC based ciphersuites from RFC5289 */
 
 #define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256    "ECDHE-ECDSA-AES128-SHA256"
@@ -574,6 +612,16 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 #define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256       "ECDH-RSA-AES128-SHA256"
 #define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384       "ECDH-RSA-AES256-SHA384"
 
+/* ECDH GCM based ciphersuites from RFC5289 */
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256    "ECDHE-ECDSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384    "ECDHE-ECDSA-AES256-GCM-SHA384"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256     "ECDH-ECDSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384     "ECDH-ECDSA-AES256-GCM-SHA384"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256      "ECDHE-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384      "ECDHE-RSA-AES256-GCM-SHA384"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256       "ECDH-RSA-AES128-GCM-SHA256"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384       "ECDH-RSA-AES256-GCM-SHA384"
+
 #define TLS_CT_RSA_SIGN                        1
 #define TLS_CT_DSS_SIGN                        2
 #define TLS_CT_RSA_FIXED_DH            3