]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
_gnutls_pkcs12_string_to_key: allow SHA384 and SHA512
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 4 Apr 2017 10:01:15 +0000 (12:01 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 4 Apr 2017 13:23:34 +0000 (15:23 +0200)
The previous implementation of the function was restricted to SHA1 and
SHA256. Extended to allow SHA384 and SHA512 as well.

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/x509/pkcs12_encr.c

index d3e8a593052266b5d8b55a70f69b89f86d184bd0..5faf75f69c21ad3e1fd713a8128a0eb67ebab9ea 100644 (file)
@@ -28,7 +28,7 @@
 #include <algorithms.h>
 
 #define MAX_PASS_LEN 256
-
+#define MAX_V_SIZE 128
 /* ID should be:
  * 3 for MAC
  * 2 for IV
@@ -48,30 +48,40 @@ _gnutls_pkcs12_string_to_key(const mac_entry_st * me,
        unsigned int i, j;
        digest_hd_st md;
        bigint_t num_b1 = NULL, num_ij = NULL;
-       bigint_t mpi512 = NULL;
+       bigint_t v_mpi = NULL;
        unsigned int pwlen;
-       uint8_t hash[MAX_HASH_SIZE], buf_b[64], buf_i[MAX_PASS_LEN + 64], *p;
-       uint8_t d[64];
+       uint8_t hash[MAX_HASH_SIZE], buf_b[MAX_V_SIZE], buf_i[MAX_PASS_LEN + MAX_V_SIZE], *p;
+       uint8_t d[MAX_V_SIZE];
        size_t cur_keylen;
        size_t n, m, plen, i_size;
        size_t slen;
        gnutls_datum_t ucs2 = {NULL, 0};
        unsigned mac_len;
-       const uint8_t buf_512[] =       /* 2^64 */
-       { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00
-       };
-
-       cur_keylen = 0;
+       uint8_t v_val[MAX_V_SIZE+1];
+       unsigned v_size = 0;
+
+       switch (me->id) {
+               case GNUTLS_DIG_SHA1:
+               case GNUTLS_DIG_SHA224:
+               case GNUTLS_DIG_SHA256:
+                       v_size = 64;
+                       break;
+               case GNUTLS_DIG_SHA384:
+               case GNUTLS_DIG_SHA512:
+                       v_size = 128;
+                       break;
+               default:
+                       break;
+       }
 
-       if (me->block_size != 64)
+       if (v_size == 0 || v_size > MAX_V_SIZE)
                return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
 
+       memset(v_val, 0, sizeof(v_val));
+       v_val[0] = 0x01; /* make it be 2^64 or 2^128 */
+
+       cur_keylen = 0;
+
        if (pw) {
                pwlen = strlen(pw);
 
@@ -99,15 +109,15 @@ _gnutls_pkcs12_string_to_key(const mac_entry_st * me,
                goto cleanup;
        }
 
-       rc = _gnutls_mpi_init_scan(&mpi512, buf_512, sizeof(buf_512));
+       rc = _gnutls_mpi_init_scan(&v_mpi, v_val, v_size+1);
        if (rc < 0) {
                gnutls_assert();
                goto cleanup;
        }
 
        /* Store salt and password in BUF_I */
-       slen = ((salt_size+63)/64) * 64;
-       plen = ((pwlen+63)/64) * 64;
+       slen = ((salt_size+v_size-1)/v_size) * v_size;
+       plen = ((pwlen+v_size-1)/v_size) * v_size;
        i_size = slen + plen;
 
        if (i_size > sizeof(buf_i)) {
@@ -140,8 +150,8 @@ _gnutls_pkcs12_string_to_key(const mac_entry_st * me,
                        gnutls_assert();
                        goto cleanup;
                }
-               memset(d, id & 0xff, 64);
-               _gnutls_hash(&md, d, 64);
+               memset(d, id & 0xff, v_size);
+               _gnutls_hash(&md, d, v_size);
                _gnutls_hash(&md, buf_i, i_size);
                _gnutls_hash_deinit(&md, hash);
                for (i = 1; i < iter; i++) {
@@ -160,9 +170,9 @@ _gnutls_pkcs12_string_to_key(const mac_entry_st * me,
                }
 
                /* need more bytes. */
-               for (i = 0; i < 64; i++)
+               for (i = 0; i < v_size; i++)
                        buf_b[i] = hash[i % mac_len];
-               n = 64;
+               n = v_size;
                rc = _gnutls_mpi_init_scan(&num_b1, buf_b, n);
                if (rc < 0) {
                        gnutls_assert();
@@ -175,21 +185,21 @@ _gnutls_pkcs12_string_to_key(const mac_entry_st * me,
                        goto cleanup;
                }
 
-               for (i = 0; i < i_size; i += 64) {
-                       n = 64;
+               for (i = 0; i < i_size; i += v_size) {
+                       n = v_size;
                        rc = _gnutls_mpi_init_scan(&num_ij, buf_i + i, n);
                        if (rc < 0) {
                                gnutls_assert();
                                goto cleanup;
                        }
 
-                       rc = _gnutls_mpi_addm(num_ij, num_ij, num_b1, mpi512);
+                       rc = _gnutls_mpi_addm(num_ij, num_ij, num_b1, v_mpi);
                        if (rc < 0) {
                                gnutls_assert();
                                goto cleanup;
                        }
 
-                       n = 64;
+                       n = v_size;
                        m = (_gnutls_mpi_get_nbits(num_ij) + 7) / 8;
 
                        memset(buf_i + i, 0, n - m);
@@ -205,7 +215,7 @@ _gnutls_pkcs12_string_to_key(const mac_entry_st * me,
       cleanup:
        _gnutls_mpi_release(&num_ij);
        _gnutls_mpi_release(&num_b1);
-       _gnutls_mpi_release(&mpi512);
+       _gnutls_mpi_release(&v_mpi);
        gnutls_free(ucs2.data);
 
        return rc;