Browse Source

Reorganize the private key encryption a bit.

master
samr7 13 years ago
parent
commit
fd4660217d
  1. 89
      util.c
  2. 2
      util.h

89
util.c

@ -416,9 +416,32 @@ PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
#endif /* OPENSSL_VERSION_NUMBER < 0x10000000L */ #endif /* OPENSSL_VERSION_NUMBER < 0x10000000L */
#define VG_PROTKEY_SALT_SIZE 4 typedef struct {
#define VG_PROTKEY_HMAC_SIZE 8 int mode;
#define VG_PROTKEY_HMAC_KEY_SIZE 16 int iterations;
const EVP_MD *(*pbkdf_hash_getter)(void);
const EVP_CIPHER *(*cipher_getter)(void);
} vg_protkey_parameters_t;
static const vg_protkey_parameters_t protkey_parameters[] = {
{ 0, 4096, EVP_sha256, EVP_aes_256_cbc },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 0, 0, NULL, NULL },
{ 1, 4096, EVP_sha256, EVP_aes_256_cbc },
};
static int static int
vg_protect_crypt(int parameter_group, vg_protect_crypt(int parameter_group,
@ -429,14 +452,14 @@ vg_protect_crypt(int parameter_group,
EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *ctx = NULL;
unsigned char *salt; unsigned char *salt;
unsigned char keymaterial[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH + unsigned char keymaterial[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH +
VG_PROTKEY_HMAC_KEY_SIZE]; EVP_MAX_MD_SIZE];
unsigned char hmac[EVP_MAX_MD_SIZE]; unsigned char hmac[EVP_MAX_MD_SIZE];
int hmac_len = 0, hmac_keylen = 0; int hmac_len = 0, hmac_keylen = 0;
int salt_len; int salt_len;
int pbkdf_iterations;
int plaintext_len = 32; int plaintext_len = 32;
int ciphertext_len; int ciphertext_len;
int pkcs7_padding = 1; int pkcs7_padding = 1;
const vg_protkey_parameters_t *params;
const EVP_CIPHER *cipher; const EVP_CIPHER *cipher;
const EVP_MD *pbkdf_digest; const EVP_MD *pbkdf_digest;
const EVP_MD *hmac_digest; const EVP_MD *hmac_digest;
@ -451,7 +474,7 @@ vg_protect_crypt(int parameter_group,
if (parameter_group < 0) { if (parameter_group < 0) {
if (enc) if (enc)
parameter_group = 0; parameter_group = 3;
else else
parameter_group = data_in[0]; parameter_group = data_in[0];
} else { } else {
@ -459,29 +482,31 @@ vg_protect_crypt(int parameter_group,
goto out; goto out;
} }
switch (parameter_group) { if (parameter_group > (sizeof(protkey_parameters) /
case VG_PROTKEY_BRIEF_PBKDF2_4096_HMAC_SHA256_AES_256_CBC: sizeof(protkey_parameters[0])))
goto out;
params = &protkey_parameters[parameter_group];
if (!params->iterations || !params->pbkdf_hash_getter)
goto out;
pbkdf_digest = params->pbkdf_hash_getter();
cipher = params->cipher_getter();
if (params->mode == 0) {
/* Brief encoding */ /* Brief encoding */
pbkdf_digest = EVP_sha256();
pbkdf_iterations = 4096;
salt_len = 4; salt_len = 4;
hmac_len = 8; hmac_len = 8;
hmac_keylen = 16; hmac_keylen = 16;
cipher = EVP_aes_256_cbc(); ciphertext_len = ((plaintext_len + cipher->block_size - 1) /
ciphertext_len = 32; cipher->block_size) * cipher->block_size;
pkcs7_padding = 0; pkcs7_padding = 0;
hmac_digest = EVP_sha256(); hmac_digest = EVP_sha256();
break; } else {
case VG_PROTKEY_PKCS_PBKDF2_4096_HMAC_SHA256_AES_256_CBC: /* PKCS-compliant encoding */
/* PKCS#7 compliant encoding */
pbkdf_digest = EVP_sha256();
pbkdf_iterations = 4096;
salt_len = 8; salt_len = 8;
cipher = EVP_aes_256_cbc(); ciphertext_len = ((plaintext_len + cipher->block_size) /
ciphertext_len = 48; cipher->block_size) * cipher->block_size;
break;
default:
goto out;
} }
if (!enc && (data_in_len != (1 + ciphertext_len + hmac_len + salt_len))) if (!enc && (data_in_len != (1 + ciphertext_len + hmac_len + salt_len)))
@ -504,7 +529,7 @@ vg_protect_crypt(int parameter_group,
PKCS5_PBKDF2_HMAC((const char *) pass, strlen(pass) + 1, PKCS5_PBKDF2_HMAC((const char *) pass, strlen(pass) + 1,
salt, salt_len, salt, salt_len,
pbkdf_iterations, params->iterations,
pbkdf_digest, pbkdf_digest,
cipher->key_len + cipher->iv_len + hmac_keylen, cipher->key_len + cipher->iv_len + hmac_keylen,
keymaterial); keymaterial);
@ -595,6 +620,9 @@ vg_protect_encode_privkey(char *out,
unsigned char ecenc[128]; unsigned char ecenc[128];
const BIGNUM *privkey; const BIGNUM *privkey;
int nbytes; int nbytes;
int restype;
restype = (keytype & 1) ? 79 : 32;
privkey = EC_KEY_get0_private_key(pkey); privkey = EC_KEY_get0_private_key(pkey);
nbytes = BN_num_bytes(privkey); nbytes = BN_num_bytes(privkey);
@ -610,7 +638,7 @@ vg_protect_encode_privkey(char *out,
OPENSSL_cleanse(ecpriv, sizeof(ecpriv)); OPENSSL_cleanse(ecpriv, sizeof(ecpriv));
ecenc[0] = 32; ecenc[0] = restype;
vg_b58_encode_check(ecenc, nbytes + 1, out); vg_b58_encode_check(ecenc, nbytes + 1, out);
nbytes = strlen(out); nbytes = strlen(out);
return nbytes; return nbytes;
@ -624,13 +652,18 @@ vg_protect_decode_privkey(EC_KEY *pkey, int *keytype,
unsigned char ecpriv[64]; unsigned char ecpriv[64];
unsigned char ecenc[128]; unsigned char ecenc[128];
BIGNUM bn; BIGNUM bn;
int restype;
int res; int res;
res = vg_b58_decode_check(encoded, ecenc, sizeof(ecenc)); res = vg_b58_decode_check(encoded, ecenc, sizeof(ecenc));
if ((res < 2) || if ((res < 2) || (res > sizeof(ecenc)))
((ecenc[0] & 0xe0) != 32) || return 0;
(res > sizeof(ecenc))) {
switch (ecenc[0]) {
case 32: restype = 128; break;
case 79: restype = 239; break;
default:
return 0; return 0;
} }
@ -649,7 +682,7 @@ vg_protect_decode_privkey(EC_KEY *pkey, int *keytype,
OPENSSL_cleanse(ecpriv, sizeof(ecpriv)); OPENSSL_cleanse(ecpriv, sizeof(ecpriv));
} }
*keytype = 128; *keytype = restype;
return res; return res;
} }

2
util.h

@ -42,7 +42,7 @@ extern int vg_decode_privkey(const char *b58encoded,
enum { enum {
VG_PROTKEY_DEFAULT = -1, VG_PROTKEY_DEFAULT = -1,
VG_PROTKEY_BRIEF_PBKDF2_4096_HMAC_SHA256_AES_256_CBC = 0, VG_PROTKEY_BRIEF_PBKDF2_4096_HMAC_SHA256_AES_256_CBC = 0,
VG_PROTKEY_PKCS_PBKDF2_4096_HMAC_SHA256_AES_256_CBC = 1, VG_PROTKEY_PKCS_PBKDF2_4096_HMAC_SHA256_AES_256_CBC = 16,
}; };
#define VG_PROTKEY_MAX_B58 128 #define VG_PROTKEY_MAX_B58 128

Loading…
Cancel
Save