Don't access EVP_MD_CTX internals directly.
[openssl.git] / ssl / s3_cbc.c
index 58da5012705ca2fb785388b8531dc9a998e9c1e1..52e294157eba276a8372faaf351d30a4497439a1 100644 (file)
@@ -53,8 +53,6 @@
  *
  */
 
-#include <stdint.h>
-
 #include "ssl_locl.h"
 
 #include <openssl/md5.h>
@@ -341,7 +339,9 @@ static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
        l2n(sha1->h3, md_out);
        l2n(sha1->h4, md_out);
        }
+#define LARGEST_DIGEST_CTX SHA_CTX
 
+#ifndef OPENSSL_NO_SHA256
 static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
        {
        SHA256_CTX *sha256 = ctx;
@@ -352,7 +352,11 @@ static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
                l2n(sha256->h[i], md_out);
                }
        }
+#undef  LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA256_CTX
+#endif
 
+#ifndef OPENSSL_NO_SHA512
 static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
        {
        SHA512_CTX *sha512 = ctx;
@@ -363,6 +367,9 @@ static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
                l2n8(sha512->h[i], md_out);
                }
        }
+#undef  LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA512_CTX
+#endif
 
 /* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
  * which ssl3_cbc_digest_record supports. */
@@ -372,14 +379,18 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
        if (FIPS_mode())
                return 0;
 #endif
-       switch (ctx->digest->type)
+       switch (EVP_MD_CTX_type(ctx))
                {
                case NID_md5:
                case NID_sha1:
+#ifndef OPENSSL_NO_SHA256
                case NID_sha224:
                case NID_sha256:
+#endif
+#ifndef OPENSSL_NO_SHA512
                case NID_sha384:
                case NID_sha512:
+#endif
                        return 1;
                default:
                        return 0;
@@ -417,14 +428,15 @@ void ssl3_cbc_digest_record(
        unsigned mac_secret_length,
        char is_sslv3)
        {
-       unsigned char md_state[sizeof(SHA512_CTX)];
+       union { double align;
+               unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state;
        void (*md_final_raw)(void *ctx, unsigned char *md_out);
        void (*md_transform)(void *ctx, const unsigned char *block);
        unsigned md_size, md_block_size = 64;
        unsigned sslv3_pad_length = 40, header_length, variance_blocks,
                 len, max_mac_bytes, num_blocks,
                 num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
-       uint64_t bits;
+       unsigned int bits;      /* at most 18 bits */
        unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
        /* hmac_pad is the masked HMAC key. */
        unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
@@ -440,35 +452,38 @@ void ssl3_cbc_digest_record(
         * many possible overflows later in this function. */
        OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024);
 
-       switch (ctx->digest->type)
+       switch (EVP_MD_CTX_type(ctx))
                {
                case NID_md5:
-                       MD5_Init((MD5_CTX*)md_state);
+                       MD5_Init((MD5_CTX*)md_state.c);
                        md_final_raw = tls1_md5_final_raw;
                        md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
                        md_size = 16;
                        sslv3_pad_length = 48;
                        break;
                case NID_sha1:
-                       SHA1_Init((SHA_CTX*)md_state);
+                       SHA1_Init((SHA_CTX*)md_state.c);
                        md_final_raw = tls1_sha1_final_raw;
                        md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
                        md_size = 20;
                        break;
+#ifndef OPENSSL_NO_SHA256
                case NID_sha224:
-                       SHA224_Init((SHA256_CTX*)md_state);
+                       SHA224_Init((SHA256_CTX*)md_state.c);
                        md_final_raw = tls1_sha256_final_raw;
                        md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
                        md_size = 224/8;
                        break;
                case NID_sha256:
-                       SHA256_Init((SHA256_CTX*)md_state);
+                       SHA256_Init((SHA256_CTX*)md_state.c);
                        md_final_raw = tls1_sha256_final_raw;
                        md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
                        md_size = 32;
                        break;
+#endif
+#ifndef OPENSSL_NO_SHA512
                case NID_sha384:
-                       SHA384_Init((SHA512_CTX*)md_state);
+                       SHA384_Init((SHA512_CTX*)md_state.c);
                        md_final_raw = tls1_sha512_final_raw;
                        md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
                        md_size = 384/8;
@@ -476,13 +491,14 @@ void ssl3_cbc_digest_record(
                        md_length_size = 16;
                        break;
                case NID_sha512:
-                       SHA512_Init((SHA512_CTX*)md_state);
+                       SHA512_Init((SHA512_CTX*)md_state.c);
                        md_final_raw = tls1_sha512_final_raw;
                        md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
                        md_size = 64;
                        md_block_size = 128;
                        md_length_size = 16;
                        break;
+#endif
                default:
                        /* ssl3_cbc_record_digest_supported should have been
                         * called first to check that the hash function is
@@ -581,17 +597,14 @@ void ssl3_cbc_digest_record(
                for (i = 0; i < md_block_size; i++)
                        hmac_pad[i] ^= 0x36;
 
-               md_transform(md_state, hmac_pad);
+               md_transform(md_state.c, hmac_pad);
                }
 
-       j = 0;
-       if (md_length_size == 16)
-               {
-               memset(length_bytes, 0, 8);
-               j = 8;
-               }
-       for (i = 0; i < 8; i++)
-               length_bytes[i+j] = bits >> (8*(7-i));
+       memset(length_bytes,0,md_length_size-4);
+       length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
+       length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
+       length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
+       length_bytes[md_length_size-1] = (unsigned char)bits;
 
        if (k > 0)
                {
@@ -602,21 +615,21 @@ void ssl3_cbc_digest_record(
                         * block that the header consumes: either 7 bytes
                         * (SHA1) or 11 bytes (MD5). */
                        unsigned overhang = header_length-md_block_size;
-                       md_transform(md_state, header);
+                       md_transform(md_state.c, header);
                        memcpy(first_block, header + md_block_size, overhang);
                        memcpy(first_block + overhang, data, md_block_size-overhang);
-                       md_transform(md_state, first_block);
+                       md_transform(md_state.c, first_block);
                        for (i = 1; i < k/md_block_size - 1; i++)
-                               md_transform(md_state, data + md_block_size*i - overhang);
+                               md_transform(md_state.c, data + md_block_size*i - overhang);
                        }
                else
                        {
                        /* k is a multiple of md_block_size. */
                        memcpy(first_block, header, 13);
                        memcpy(first_block+13, data, md_block_size-13);
-                       md_transform(md_state, first_block);
+                       md_transform(md_state.c, first_block);
                        for (i = 1; i < k/md_block_size; i++)
-                               md_transform(md_state, data + md_block_size*i - 13);
+                               md_transform(md_state.c, data + md_block_size*i - 13);
                        }
                }
 
@@ -666,8 +679,8 @@ void ssl3_cbc_digest_record(
                        block[j] = b;
                        }
 
-               md_transform(md_state, block);
-               md_final_raw(md_state, block);
+               md_transform(md_state.c, block);
+               md_final_raw(md_state.c, block);
                /* If this is index_b, copy the hash value to |mac_out|. */
                for (j = 0; j < md_size; j++)
                        mac_out[j] |= block[j]&is_block_b;