#include "pk.h"
#define PBES1_DES_MD5_OID "1.2.840.113549.1.5.3"
+#define PBES1_DES_SHA1_OID "1.2.840.113549.1.5.10"
#define PBES2_OID "1.2.840.113549.1.5.13"
#define PBKDF2_OID "1.2.840.113549.1.5.12"
.desc = NULL,
.iv_name = NULL,
.decrypt_only = 1 },
+ { .schema = PBES1_DES_SHA1,
+ .name = "PBES1-DES-CBC-SHA1",
+ .flag = GNUTLS_PKCS_PBES1_DES_SHA1,
+ .cipher = GNUTLS_CIPHER_DES_CBC,
+ .pbes2 = 0,
+ .cipher_oid = PBES1_DES_SHA1_OID,
+ .write_oid = PBES1_DES_SHA1_OID,
+ .desc = NULL,
+ .iv_name = NULL,
+ .decrypt_only = 1 },
{ .schema = PBES2_3DES,
.name = "PBES2-3DES-CBC",
.flag = GNUTLS_PKCS_PBES2_3DES,
*schema = p->schema;
return 0;
- } else if (*schema == PBES1_DES_MD5) {
+ } else if (*schema == PBES1_DES_MD5 || *schema == PBES1_DES_SHA1) {
return _gnutls_read_pbkdf1_params(data, data_size, kdf_params,
enc_params);
} else { /* PKCS #12 schema */
if (ret < 0)
goto error;
goto cleanup;
+ } else if (schema == PBES1_DES_SHA1) {
+ ret = _gnutls_decrypt_pbes1_des_sha1_data(password, pass_len,
+ kdf_params,
+ enc_params, &enc,
+ decrypted_data);
+ if (ret < 0)
+ goto error;
+ goto cleanup;
}
if (kdf_params->key_size == 0) {
#include "x509_int.h"
#include "pkcs7_int.h"
#include "algorithms.h"
-#include <nettle/md5.h>
/* This file includes support for PKCS#8 PBES1 with DES and MD5.
* We only support decryption for compatibility with other software.
return ret;
}
-static void pbkdf1_md5(const char *password, unsigned password_len,
- const uint8_t salt[8], unsigned iter_count,
- unsigned key_size, uint8_t *key)
+static int pbkdf1(gnutls_digest_algorithm_t dig, const char *password,
+ unsigned password_len, const uint8_t salt[8],
+ unsigned iter_count, unsigned key_size, uint8_t *key)
{
- struct md5_ctx ctx;
- uint8_t tmp[16];
+ uint8_t tmp[20];
unsigned i;
+ gnutls_hash_hd_t hd;
+ int ret;
if (key_size > sizeof(tmp))
abort();
- for (i = 0; i < iter_count; i++) {
- md5_init(&ctx);
- if (i == 0) {
- md5_update(&ctx, password_len, (uint8_t *)password);
- md5_update(&ctx, 8, salt);
- md5_digest(&ctx, 16, tmp);
- } else {
- md5_update(&ctx, 16, tmp);
- md5_digest(&ctx, 16, tmp);
- }
+ ret = gnutls_hash_init(&hd, dig);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ ret = gnutls_hash(hd, (uint8_t *)password, password_len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ ret = gnutls_hash(hd, salt, 8);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ gnutls_hash_deinit(hd, tmp);
+
+ for (i = 1; i < iter_count; i++) {
+ ret = gnutls_hash_init(&hd, dig);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ ret = gnutls_hash(hd, tmp, gnutls_hash_get_len(dig));
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ gnutls_hash_deinit(hd, tmp);
}
memcpy(key, tmp, key_size);
- return;
+ return 0;
}
-int _gnutls_decrypt_pbes1_des_md5_data(const char *password,
- unsigned password_len,
- const struct pbkdf2_params *kdf_params,
- const struct pbe_enc_params *enc_params,
- const gnutls_datum_t *encrypted_data,
- gnutls_datum_t *decrypted_data)
+static int _gnutls_decrypt_pbes1_des_data(
+ gnutls_digest_algorithm_t dig, const char *password,
+ unsigned password_len, const struct pbkdf2_params *kdf_params,
+ const struct pbe_enc_params *enc_params,
+ const gnutls_datum_t *encrypted_data, gnutls_datum_t *decrypted_data)
{
int result;
gnutls_datum_t dkey, d_iv;
gnutls_cipher_hd_t ch;
- uint8_t key[16];
+ uint8_t key[20];
const unsigned block_size = 8;
if (enc_params->cipher != GNUTLS_CIPHER_DES_CBC)
/* generate the key
*/
- pbkdf1_md5(password, password_len, kdf_params->salt,
- kdf_params->iter_count, sizeof(key), key);
+ result = pbkdf1(dig, password, password_len, kdf_params->salt,
+ kdf_params->iter_count, gnutls_hash_get_len(dig), key);
+ if (result < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(result);
+ }
dkey.data = key;
dkey.size = 8;
return result;
}
+
+int _gnutls_decrypt_pbes1_des_md5_data(const char *password,
+ unsigned password_len,
+ const struct pbkdf2_params *kdf_params,
+ const struct pbe_enc_params *enc_params,
+ const gnutls_datum_t *encrypted_data,
+ gnutls_datum_t *decrypted_data)
+{
+ return _gnutls_decrypt_pbes1_des_data(GNUTLS_DIG_MD5, password,
+ password_len, kdf_params,
+ enc_params, encrypted_data,
+ decrypted_data);
+}
+
+int _gnutls_decrypt_pbes1_des_sha1_data(const char *password,
+ unsigned password_len,
+ const struct pbkdf2_params *kdf_params,
+ const struct pbe_enc_params *enc_params,
+ const gnutls_datum_t *encrypted_data,
+ gnutls_datum_t *decrypted_data)
+{
+ return _gnutls_decrypt_pbes1_des_data(GNUTLS_DIG_SHA1, password,
+ password_len, kdf_params,
+ enc_params, encrypted_data,
+ decrypted_data);
+}