Browse code

OpenSSL: don't use direct access to the internal of HMAC_CTX

OpenSSL 1.1 does not allow us to directly access the internal of
any data type, including HMAC_CTX. We have to use the defined
functions to do so.

Compatibility with OpenSSL 1.0 is kept by defining the corresponding
functions when they are not found in the library.

Signed-off-by: Emmanuel Deloget <logout@free.fr>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <20170612134330.20971-8-logout@free.fr>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14797.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Emmanuel Deloget authored on 2017/06/12 22:43:29
Showing 8 changed files
... ...
@@ -921,6 +921,10 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
921 921
 		[ \
922 922
 			EVP_CIPHER_CTX_new \
923 923
 			EVP_CIPHER_CTX_free \
924
+			HMAC_CTX_new \
925
+			HMAC_CTX_free \
926
+			HMAC_CTX_reset \
927
+			HMAC_CTX_init \
924 928
 			EVP_MD_CTX_new \
925 929
 			EVP_MD_CTX_free \
926 930
 			EVP_MD_CTX_reset \
... ...
@@ -853,7 +853,7 @@ init_key_ctx(struct key_ctx *ctx, struct key *key,
853 853
     }
854 854
     if (kt->digest && kt->hmac_length > 0)
855 855
     {
856
-        ALLOC_OBJ(ctx->hmac, hmac_ctx_t);
856
+        ctx->hmac = hmac_ctx_new();
857 857
         hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest);
858 858
 
859 859
         msg(D_HANDSHAKE,
... ...
@@ -884,7 +884,7 @@ free_key_ctx(struct key_ctx *ctx)
884 884
     if (ctx->hmac)
885 885
     {
886 886
         hmac_ctx_cleanup(ctx->hmac);
887
-        free(ctx->hmac);
887
+        hmac_ctx_free(ctx->hmac);
888 888
         ctx->hmac = NULL;
889 889
     }
890 890
     ctx->implicit_iv_len = 0;
... ...
@@ -583,6 +583,20 @@ void md_ctx_final(md_ctx_t *ctx, uint8_t *dst);
583 583
  */
584 584
 
585 585
 /*
586
+ * Create a new HMAC context
587
+ *
588
+ * @return              A new HMAC context
589
+ */
590
+hmac_ctx_t *hmac_ctx_new(void);
591
+
592
+/*
593
+ * Free an existing HMAC context
594
+ *
595
+ * @param  ctx           HMAC context to free
596
+ */
597
+void hmac_ctx_free(hmac_ctx_t *ctx);
598
+
599
+/*
586 600
  * Initialises the given HMAC context, using the given digest
587 601
  * and key.
588 602
  *
... ...
@@ -840,6 +840,21 @@ md_ctx_final(mbedtls_md_context_t *ctx, uint8_t *dst)
840 840
 /*
841 841
  * TODO: re-enable dmsg for crypto debug
842 842
  */
843
+
844
+mbedtls_md_context_t *
845
+hmac_ctx_new(void)
846
+{
847
+    mbedtls_md_context_t *ctx;
848
+    ALLOC_OBJ(ctx, mbedtls_md_context_t);
849
+    return ctx;
850
+}
851
+
852
+void
853
+hmac_ctx_free(mbedtls_md_context_t *ctx)
854
+{
855
+    free(ctx);
856
+}
857
+
843 858
 void
844 859
 hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, int key_len,
845 860
               const mbedtls_md_info_t *kt)
... ...
@@ -910,6 +910,19 @@ md_ctx_final(EVP_MD_CTX *ctx, uint8_t *dst)
910 910
  *
911 911
  */
912 912
 
913
+HMAC_CTX *
914
+hmac_ctx_new(void)
915
+{
916
+    HMAC_CTX *ctx = HMAC_CTX_new();
917
+    check_malloc_return(ctx);
918
+    return ctx;
919
+}
920
+
921
+void
922
+hmac_ctx_free(HMAC_CTX *ctx)
923
+{
924
+    HMAC_CTX_free(ctx);
925
+}
913 926
 
914 927
 void
915 928
 hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len,
... ...
@@ -917,8 +930,6 @@ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len,
917 917
 {
918 918
     ASSERT(NULL != kt && NULL != ctx);
919 919
 
920
-    CLEAR(*ctx);
921
-
922 920
     HMAC_CTX_init(ctx);
923 921
     HMAC_Init_ex(ctx, key, key_len, kt, NULL);
924 922
 
... ...
@@ -929,7 +940,7 @@ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len,
929 929
 void
930 930
 hmac_ctx_cleanup(HMAC_CTX *ctx)
931 931
 {
932
-    HMAC_CTX_cleanup(ctx);
932
+    HMAC_CTX_reset(ctx);
933 933
 }
934 934
 
935 935
 int
... ...
@@ -85,13 +85,13 @@ static void
85 85
 gen_hmac_md5(const char *data, int data_len, const char *key, int key_len,char *result)
86 86
 {
87 87
     const md_kt_t *md5_kt = md_kt_get("MD5");
88
-    hmac_ctx_t hmac_ctx;
89
-    CLEAR(hmac_ctx);
88
+    hmac_ctx_t *hmac_ctx = hmac_ctx_new();
90 89
 
91
-    hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt);
92
-    hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len);
93
-    hmac_ctx_final(&hmac_ctx, (unsigned char *)result);
94
-    hmac_ctx_cleanup(&hmac_ctx);
90
+    hmac_ctx_init(hmac_ctx, key, key_len, md5_kt);
91
+    hmac_ctx_update(hmac_ctx, (const unsigned char *)data, data_len);
92
+    hmac_ctx_final(hmac_ctx, (unsigned char *)result);
93
+    hmac_ctx_cleanup(hmac_ctx);
94
+    hmac_ctx_free(hmac_ctx);
95 95
 }
96 96
 
97 97
 static void
... ...
@@ -116,6 +116,71 @@ EVP_CIPHER_CTX_new(void)
116 116
 }
117 117
 #endif
118 118
 
119
+#if !defined(HAVE_HMAC_CTX_RESET)
120
+/**
121
+ * Reset a HMAC context
122
+ *
123
+ * @param ctx                 The HMAC context
124
+ * @return                    1 on success, 0 on error
125
+ */
126
+static inline int
127
+HMAC_CTX_reset(HMAC_CTX *ctx)
128
+{
129
+    HMAC_CTX_cleanup(ctx);
130
+    return 1;
131
+}
132
+#endif
133
+
134
+#if !defined(HAVE_HMAC_CTX_INIT)
135
+/**
136
+ * Init a HMAC context
137
+ *
138
+ * @param ctx                 The HMAC context
139
+ *
140
+ * Contrary to many functions in this file, HMAC_CTX_init() is not
141
+ * an OpenSSL 1.1 function: it comes from previous versions and was
142
+ * removed in v1.1. As a consequence, there is no distincting in
143
+ * v1.1 between a cleanup, and init and a reset. Yet, previous OpenSSL
144
+ * version need this distinction.
145
+ *
146
+ * In order to respect previous OpenSSL versions, we implement init
147
+ * as reset for OpenSSL 1.1+.
148
+ */
149
+static inline void
150
+HMAC_CTX_init(HMAC_CTX *ctx)
151
+{
152
+    HMAC_CTX_reset(ctx);
153
+}
154
+#endif
155
+
156
+#if !defined(HAVE_HMAC_CTX_FREE)
157
+/**
158
+ * Free an existing HMAC context
159
+ *
160
+ * @param ctx                 The HMAC context
161
+ */
162
+static inline void
163
+HMAC_CTX_free(HMAC_CTX *c)
164
+{
165
+	free(c);
166
+}
167
+#endif
168
+
169
+#if !defined(HAVE_HMAC_CTX_NEW)
170
+/**
171
+ * Allocate a new HMAC context object
172
+ *
173
+ * @return                    A zero'ed HMAC context object
174
+ */
175
+static inline HMAC_CTX *
176
+HMAC_CTX_new(void)
177
+{
178
+    HMAC_CTX *ctx = NULL;
179
+    ALLOC_OBJ_CLEAR(ctx, HMAC_CTX);
180
+    return ctx;
181
+}
182
+#endif
183
+
119 184
 #if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA)
120 185
 /**
121 186
  * Fetch the default password callback user data from the SSL context
... ...
@@ -1606,8 +1606,8 @@ tls1_P_hash(const md_kt_t *md_kt,
1606 1606
 {
1607 1607
     struct gc_arena gc = gc_new();
1608 1608
     int chunk;
1609
-    hmac_ctx_t ctx;
1610
-    hmac_ctx_t ctx_tmp;
1609
+    hmac_ctx_t *ctx;
1610
+    hmac_ctx_t *ctx_tmp;
1611 1611
     uint8_t A1[MAX_HMAC_KEY_LENGTH];
1612 1612
     unsigned int A1_len;
1613 1613
 
... ...
@@ -1616,8 +1616,8 @@ tls1_P_hash(const md_kt_t *md_kt,
1616 1616
     const uint8_t *out_orig = out;
1617 1617
 #endif
1618 1618
 
1619
-    CLEAR(ctx);
1620
-    CLEAR(ctx_tmp);
1619
+    ctx = hmac_ctx_new();
1620
+    ctx_tmp = hmac_ctx_new();
1621 1621
 
1622 1622
     dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
1623 1623
     dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
... ...
@@ -1625,36 +1625,38 @@ tls1_P_hash(const md_kt_t *md_kt,
1625 1625
     chunk = md_kt_size(md_kt);
1626 1626
     A1_len = md_kt_size(md_kt);
1627 1627
 
1628
-    hmac_ctx_init(&ctx, sec, sec_len, md_kt);
1629
-    hmac_ctx_init(&ctx_tmp, sec, sec_len, md_kt);
1628
+    hmac_ctx_init(ctx, sec, sec_len, md_kt);
1629
+    hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt);
1630 1630
 
1631
-    hmac_ctx_update(&ctx,seed,seed_len);
1632
-    hmac_ctx_final(&ctx, A1);
1631
+    hmac_ctx_update(ctx,seed,seed_len);
1632
+    hmac_ctx_final(ctx, A1);
1633 1633
 
1634 1634
     for (;; )
1635 1635
     {
1636
-        hmac_ctx_reset(&ctx);
1637
-        hmac_ctx_reset(&ctx_tmp);
1638
-        hmac_ctx_update(&ctx,A1,A1_len);
1639
-        hmac_ctx_update(&ctx_tmp,A1,A1_len);
1640
-        hmac_ctx_update(&ctx,seed,seed_len);
1636
+        hmac_ctx_reset(ctx);
1637
+        hmac_ctx_reset(ctx_tmp);
1638
+        hmac_ctx_update(ctx,A1,A1_len);
1639
+        hmac_ctx_update(ctx_tmp,A1,A1_len);
1640
+        hmac_ctx_update(ctx,seed,seed_len);
1641 1641
 
1642 1642
         if (olen > chunk)
1643 1643
         {
1644
-            hmac_ctx_final(&ctx, out);
1644
+            hmac_ctx_final(ctx, out);
1645 1645
             out += chunk;
1646 1646
             olen -= chunk;
1647
-            hmac_ctx_final(&ctx_tmp, A1); /* calc the next A1 value */
1647
+            hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
1648 1648
         }
1649 1649
         else    /* last one */
1650 1650
         {
1651
-            hmac_ctx_final(&ctx, A1);
1651
+            hmac_ctx_final(ctx, A1);
1652 1652
             memcpy(out,A1,olen);
1653 1653
             break;
1654 1654
         }
1655 1655
     }
1656
-    hmac_ctx_cleanup(&ctx);
1657
-    hmac_ctx_cleanup(&ctx_tmp);
1656
+    hmac_ctx_cleanup(ctx);
1657
+    hmac_ctx_free(ctx);
1658
+    hmac_ctx_cleanup(ctx_tmp);
1659
+    hmac_ctx_free(ctx_tmp);
1658 1660
     secure_memzero(A1, sizeof(A1));
1659 1661
 
1660 1662
     dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));