mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 12:14:38 +02:00
pkcs#5 v.20 and pkcs#12 private encryption for pkcs#8 keys
This commit is contained in:
11
certs/server-keyPkcs8Enc12.pem
Normal file
11
certs/server-keyPkcs8Enc12.pem
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||||
|
MIIBgjAcBgoqhkiG9w0BDAEDMA4ECDkwZMQEXsc8AgIIAASCAWAswojJ2ac33Tak
|
||||||
|
A8ol6daT+VLEtVwgh9AMO8NE/2xvPZFd3758j/9136k/dsci59ZbvnAVnOURf8Sa
|
||||||
|
MW0jaE+JnrnEdGDZAuODONGCtKdBx3fntHw6qRYIY0t7yhLCCRdeoVH6XK60JUtS
|
||||||
|
vzi+Hitvg5ObzV1RpiockVCxGJDAizDrXMgQO7N7doeb9fypoBx5IFgLztWONFAg
|
||||||
|
A9rQrd5CnkgEbOygRYMduv6fX+uEXWrHEB3vDI6HY5k+VHjx2XLGmNOH1goiv+9p
|
||||||
|
DA4n4YpN45xRQUDKmx2T6kyULnMoG7Tf/le2qtJ2nja7697yk8zeEkZnR+UD2IXh
|
||||||
|
/A5eyhAquiM5qDbbV46ydOh2Aji6vI8E8/ZnYk2SJ2/VVlNro/tL0XELYdjBBFnI
|
||||||
|
SfEtCp1QWWtQdCAPipWzgmsEHKkk4ihmHQqTjmoJ0Pl9XbhxvqHUUrKdHXVJtksZ
|
||||||
|
TmvgXItk
|
||||||
|
-----END ENCRYPTED PRIVATE KEY-----
|
11
certs/server-keyPkcs8Enc2.pem
Normal file
11
certs/server-keyPkcs8Enc2.pem
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||||
|
MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIBI6Zodac3rQCAggA
|
||||||
|
MBQGCCqGSIb3DQMHBAjJZP0y7jYpRwSCAWDKV70/DSueiztJHeMKow93Fd/KXDpU
|
||||||
|
PGTtlz+lfmOUcGTTt5PwSI2rjHX+QeFTCeb2j9bekcWcaW2iIO8FDRJm1djdKVh0
|
||||||
|
mO2kAxM0W2s+GoR7T6ByQSrqKp2NL6Ug/B6od2xZ6/0tvcB4Ig+10ljL3/pT3T9M
|
||||||
|
EYCQ5gjaGhPlJIZhFIwmh6x+Pz+d2bkmXObasKEhwRMhJU9GYhKhWB2fOfl8zWlb
|
||||||
|
tIDcWBf2rCZUfk3LFx/FrV0NOIY5Jmpm/xQt2gdBIos9LNV16HQOqHkhPBhGXP9D
|
||||||
|
WZGTrpxgClpZhCUJ+LvqZbAp1dXbfrrElrux0y2zmSGxWP9z8cmfC1SHgBIxcD36
|
||||||
|
CymYSD0s1hPMH4sFoCM6uyEFfK5KwRpYc3IKfEzvkk9+ZTBYpryzJNDqR1Xpfklp
|
||||||
|
19m2qz9aJjkIgV4afydQWHYEKVm5IS/PcRVl0ZWkgxJXNHRmLd7HWysS
|
||||||
|
-----END ENCRYPTED PRIVATE KEY-----
|
@@ -79,19 +79,28 @@ enum DN_Tags {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum PBES {
|
enum PBES {
|
||||||
PBE_MD5_DES = 0,
|
PBE_MD5_DES = 0,
|
||||||
PBE_SHA1_DES = 1
|
PBE_SHA1_DES = 1,
|
||||||
|
PBE_SHA1_DES3 = 2,
|
||||||
|
PBE_SHA1_RC4_128 = 3,
|
||||||
|
PBES2 = 13 /* algo ID */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ENCRYPTION_TYPES {
|
enum ENCRYPTION_TYPES {
|
||||||
DES_TYPE = 0
|
DES_TYPE = 0,
|
||||||
|
DES3_TYPE = 1,
|
||||||
|
RC4_TYPE = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Misc_ASN {
|
enum Misc_ASN {
|
||||||
ASN_NAME_MAX = 256,
|
ASN_NAME_MAX = 256,
|
||||||
MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */
|
MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */
|
||||||
|
MAX_IV_SIZE = 64, /* MAX PKCS Iv length */
|
||||||
MAX_KEY_SIZE = 64, /* MAX PKCS Key length */
|
MAX_KEY_SIZE = 64, /* MAX PKCS Key length */
|
||||||
PKCS5 = 5, /* PKCS oid tag */
|
PKCS5 = 5, /* PKCS oid tag */
|
||||||
|
PKCS5v2 = 6, /* PKCS #5 v2.0 */
|
||||||
|
PKCS12 = 12, /* PKCS #12 */
|
||||||
|
MAX_UNICODE_SZ = 256,
|
||||||
SHA_SIZE = 20,
|
SHA_SIZE = 20,
|
||||||
RSA_INTS = 8, /* RSA ints in private key */
|
RSA_INTS = 8, /* RSA ints in private key */
|
||||||
MIN_DATE_SIZE = 13,
|
MIN_DATE_SIZE = 13,
|
||||||
@@ -155,6 +164,11 @@ enum Ecc_Sum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum KDF_Sum {
|
||||||
|
PBKDF2_OID = 660
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Certificate file Type */
|
/* Certificate file Type */
|
||||||
enum CertType {
|
enum CertType {
|
||||||
CERT_TYPE = 0,
|
CERT_TYPE = 0,
|
||||||
|
@@ -298,6 +298,7 @@ int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
|
|||||||
int mp_mul_d (mp_int * a, mp_digit b, mp_int * c);
|
int mp_mul_d (mp_int * a, mp_digit b, mp_int * c);
|
||||||
int mp_2expt (mp_int * a, int b);
|
int mp_2expt (mp_int * a, int b);
|
||||||
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
|
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
|
||||||
|
int mp_add_d (mp_int* a, mp_digit b, mp_int* c);
|
||||||
/* end support added functions */
|
/* end support added functions */
|
||||||
|
|
||||||
/* added */
|
/* added */
|
||||||
|
@@ -39,6 +39,8 @@ int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
|
|||||||
int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
|
int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
|
||||||
int sLen, int iterations, int kLen, int hashType);
|
int sLen, int iterations, int kLen, int hashType);
|
||||||
|
|
||||||
|
int PKCS12_PBKDF(byte* output, const byte* passwd, int pLen, const byte* salt,
|
||||||
|
int sLen, int iterations, int kLen, int hashType, int purpose);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -620,6 +620,7 @@ int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, mp_int*
|
|||||||
|
|
||||||
int mp_add (mp_int * a, mp_int * b, mp_int * c);
|
int mp_add (mp_int * a, mp_int * b, mp_int * c);
|
||||||
int mp_sub (mp_int * a, mp_int * b, mp_int * c);
|
int mp_sub (mp_int * a, mp_int * b, mp_int * c);
|
||||||
|
int mp_add_d (mp_int * a, mp_digit b, mp_int * c);
|
||||||
|
|
||||||
int mp_mul (mp_int * a, mp_int * b, mp_int * c);
|
int mp_mul (mp_int * a, mp_int * b, mp_int * c);
|
||||||
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
|
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
|
||||||
|
@@ -519,12 +519,35 @@ int ToTraditional(byte* input, word32 sz)
|
|||||||
|
|
||||||
/* Check To see if PKCS version algo is supported, set id if it is return 0
|
/* Check To see if PKCS version algo is supported, set id if it is return 0
|
||||||
< 0 on error */
|
< 0 on error */
|
||||||
static int CheckAlgo(int version, int algo, int* id)
|
static int CheckAlgo(int first, int second, int* id, int* version)
|
||||||
{
|
{
|
||||||
if (version != PKCS5)
|
*id = -1;
|
||||||
|
*version = PKCS5; /* default */
|
||||||
|
|
||||||
|
if (first == 1) {
|
||||||
|
switch (second) {
|
||||||
|
case 1:
|
||||||
|
*id = PBE_SHA1_RC4_128;
|
||||||
|
*version = PKCS12;
|
||||||
|
return 0;
|
||||||
|
case 3:
|
||||||
|
*id = PBE_SHA1_DES3;
|
||||||
|
*version = PKCS12;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first != PKCS5)
|
||||||
return ASN_INPUT_E; /* VERSION ERROR */
|
return ASN_INPUT_E; /* VERSION ERROR */
|
||||||
|
|
||||||
switch (algo) {
|
if (second == PBES2) {
|
||||||
|
*version = PKCS5v2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (second) {
|
||||||
case 3: /* see RFC 2898 for ids */
|
case 3: /* see RFC 2898 for ids */
|
||||||
*id = PBE_MD5_DES;
|
*id = PBE_MD5_DES;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -538,44 +561,129 @@ static int CheckAlgo(int version, int algo, int* id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check To see if PKCS v2 algo is supported, set id if it is return 0
|
||||||
|
< 0 on error */
|
||||||
|
static int CheckAlgoV2(int oid, int* id)
|
||||||
|
{
|
||||||
|
switch (oid) {
|
||||||
|
case 69:
|
||||||
|
*id = PBE_SHA1_DES;
|
||||||
|
return 0;
|
||||||
|
case 652:
|
||||||
|
*id = PBE_SHA1_DES3;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Decrypt intput in place from parameters based on id */
|
/* Decrypt intput in place from parameters based on id */
|
||||||
static int DecryptKey(const char* password, int passwordSz, byte* salt,
|
static int DecryptKey(const char* password, int passwordSz, byte* salt,
|
||||||
int saltSz, int iterations, int id, byte* input, int length)
|
int saltSz, int iterations, int id, byte* input,
|
||||||
|
int length, int version, byte* cbcIv)
|
||||||
{
|
{
|
||||||
byte key[MAX_KEY_SIZE];
|
byte key[MAX_KEY_SIZE];
|
||||||
int hashType;
|
int hashType;
|
||||||
int derivedLen;
|
int derivedLen;
|
||||||
int decryptionType;
|
int decryptionType;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case PBE_MD5_DES:
|
case PBE_MD5_DES:
|
||||||
hashType = MD5;
|
hashType = MD5;
|
||||||
derivedLen = 16;
|
derivedLen = 16; /* may need iv for v1.5 */
|
||||||
decryptionType = DES_TYPE;
|
decryptionType = DES_TYPE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PBE_SHA1_DES:
|
case PBE_SHA1_DES:
|
||||||
hashType = SHA;
|
hashType = SHA;
|
||||||
derivedLen = 16;
|
derivedLen = 16; /* may need iv for v1.5 */
|
||||||
decryptionType = DES_TYPE;
|
decryptionType = DES_TYPE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PBE_SHA1_DES3:
|
||||||
|
hashType = SHA;
|
||||||
|
derivedLen = 32; /* may need iv for v1.5 */
|
||||||
|
decryptionType = DES3_TYPE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PBE_SHA1_RC4_128:
|
||||||
|
hashType = SHA;
|
||||||
|
derivedLen = 16;
|
||||||
|
decryptionType = RC4_TYPE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1; /* unknown algo id */
|
return -1; /* unknown algo id */
|
||||||
}
|
}
|
||||||
|
|
||||||
PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations,
|
if (version == PKCS5v2)
|
||||||
derivedLen, hashType);
|
ret = PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations,
|
||||||
|
derivedLen, hashType);
|
||||||
|
else if (version == PKCS5)
|
||||||
|
ret = PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations,
|
||||||
|
derivedLen, hashType);
|
||||||
|
else if (version == PKCS12) {
|
||||||
|
int i, idx = 0;
|
||||||
|
byte unicodePasswd[MAX_UNICODE_SZ];
|
||||||
|
|
||||||
|
if ( (passwordSz * 2 + 2) > sizeof(unicodePasswd))
|
||||||
|
return -1; /* unicode passwd too big */
|
||||||
|
|
||||||
|
for (i = 0; i < passwordSz; i++) {
|
||||||
|
unicodePasswd[idx++] = 0x00;
|
||||||
|
unicodePasswd[idx++] = (byte)password[i];
|
||||||
|
}
|
||||||
|
/* add trailing NULL */
|
||||||
|
unicodePasswd[idx++] = 0x00;
|
||||||
|
unicodePasswd[idx++] = 0x00;
|
||||||
|
|
||||||
|
ret = PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
|
||||||
|
iterations, derivedLen, hashType, 1);
|
||||||
|
if (decryptionType != RC4_TYPE)
|
||||||
|
ret += PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
|
||||||
|
iterations, 8, hashType, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
switch (decryptionType) {
|
switch (decryptionType) {
|
||||||
case DES_TYPE:
|
case DES_TYPE:
|
||||||
{
|
{
|
||||||
Des dec;
|
Des dec;
|
||||||
Des_SetKey(&dec, key, key + 8, DES_DECRYPTION);
|
byte* desIv = key + 8;
|
||||||
|
|
||||||
|
if (version == PKCS5v2 || version == PKCS12)
|
||||||
|
desIv = cbcIv;
|
||||||
|
Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
|
||||||
Des_CbcDecrypt(&dec, input, input, length);
|
Des_CbcDecrypt(&dec, input, input, length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DES3_TYPE:
|
||||||
|
{
|
||||||
|
Des3 dec;
|
||||||
|
byte* desIv = key + 24;
|
||||||
|
|
||||||
|
if (version == PKCS5v2 || version == PKCS12)
|
||||||
|
desIv = cbcIv;
|
||||||
|
Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
|
||||||
|
Des3_CbcDecrypt(&dec, input, input, length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RC4_TYPE:
|
||||||
|
{
|
||||||
|
Arc4 dec;
|
||||||
|
|
||||||
|
Arc4SetKey(&dec, key, derivedLen);
|
||||||
|
Arc4Process(&dec, input, input, length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1; /* unknown algo id */
|
return -1; /* unknown algo id */
|
||||||
}
|
}
|
||||||
@@ -589,8 +697,10 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt,
|
|||||||
int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
|
int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
|
||||||
{
|
{
|
||||||
word32 inOutIdx = 0, oid;
|
word32 inOutIdx = 0, oid;
|
||||||
int type, algo, version, length, iterations, saltSz, id;
|
int type, first, second, length, iterations, saltSz, id;
|
||||||
|
int version;
|
||||||
byte salt[MAX_SALT_SIZE];
|
byte salt[MAX_SALT_SIZE];
|
||||||
|
byte cbcIv[MAX_IV_SIZE];
|
||||||
|
|
||||||
if (GetSequence(input, &inOutIdx, &length) < 0)
|
if (GetSequence(input, &inOutIdx, &length) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
@@ -601,12 +711,27 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
|
|||||||
if (GetAlgoId(input, &inOutIdx, &oid) < 0)
|
if (GetAlgoId(input, &inOutIdx, &oid) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
version = input[inOutIdx - 2]; /* PKCS version alwyas 2nd to last byte */
|
first = input[inOutIdx - 2]; /* PKCS version alwyas 2nd to last byte */
|
||||||
algo = input[inOutIdx - 1]; /* version.algo, algo id last byte */
|
second = input[inOutIdx - 1]; /* version.algo, algo id last byte */
|
||||||
|
|
||||||
if (CheckAlgo(version, algo, &id) < 0)
|
if (CheckAlgo(first, second, &id, &version) < 0)
|
||||||
return ASN_INPUT_E; /* Algo ID error */
|
return ASN_INPUT_E; /* Algo ID error */
|
||||||
|
|
||||||
|
if (version == PKCS5v2) {
|
||||||
|
|
||||||
|
if (GetSequence(input, &inOutIdx, &length) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if ((word32)length > (sz - inOutIdx))
|
||||||
|
return ASN_INPUT_E;
|
||||||
|
|
||||||
|
if (GetAlgoId(input, &inOutIdx, &oid) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (oid != PBKDF2_OID)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetSequence(input, &inOutIdx, &length) < 0)
|
if (GetSequence(input, &inOutIdx, &length) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
@@ -631,6 +756,27 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
|
|||||||
if (GetShortInt(input, &inOutIdx, &iterations) < 0)
|
if (GetShortInt(input, &inOutIdx, &iterations) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (version == PKCS5v2) {
|
||||||
|
/* get encryption algo */
|
||||||
|
if (GetAlgoId(input, &inOutIdx, &oid) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (CheckAlgoV2(oid, &id) < 0)
|
||||||
|
return ASN_PARSE_E; /* PKCS v2 algo id error */
|
||||||
|
|
||||||
|
if (input[inOutIdx++] != ASN_OCTET_STRING)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (GetLength(input, &inOutIdx, &length) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if ((word32)length > (sz - inOutIdx))
|
||||||
|
return ASN_INPUT_E;
|
||||||
|
|
||||||
|
XMEMCPY(cbcIv, &input[inOutIdx], length);
|
||||||
|
inOutIdx += length;
|
||||||
|
}
|
||||||
|
|
||||||
if (input[inOutIdx++] != ASN_OCTET_STRING)
|
if (input[inOutIdx++] != ASN_OCTET_STRING)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
@@ -641,7 +787,7 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
|
|||||||
return ASN_INPUT_E;
|
return ASN_INPUT_E;
|
||||||
|
|
||||||
if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
|
if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
|
||||||
input + inOutIdx, length) < 0)
|
input + inOutIdx, length, version, cbcIv) < 0)
|
||||||
return ASN_INPUT_E; /* decrypt failure */
|
return ASN_INPUT_E; /* decrypt failure */
|
||||||
|
|
||||||
XMEMMOVE(input, input + inOutIdx, length);
|
XMEMMOVE(input, input + inOutIdx, length);
|
||||||
|
@@ -3591,7 +3591,7 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(CYASSL_KEY_GEN) || defined(HAVE_ECC)
|
#if defined(CYASSL_KEY_GEN) || defined(HAVE_ECC) || !defined(NO_PWDBASED)
|
||||||
|
|
||||||
/* c = a * a (mod b) */
|
/* c = a * a (mod b) */
|
||||||
int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
|
int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "pwdbased.h"
|
#include "pwdbased.h"
|
||||||
#include "ctc_hmac.h"
|
#include "ctc_hmac.h"
|
||||||
|
#include "integer.h"
|
||||||
#ifdef CYASSL_SHA512
|
#ifdef CYASSL_SHA512
|
||||||
#include "sha512.h"
|
#include "sha512.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -148,5 +149,159 @@ int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
|
||||||
|
int saltLen, int iterations, int kLen, int hashType, int id)
|
||||||
|
{
|
||||||
|
/* all in bytes instead of bits */
|
||||||
|
word32 u, v, dLen, pLen, iLen, sLen, totalLen;
|
||||||
|
int dynamic = 0;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
byte *D, *S, *P, *I;
|
||||||
|
byte staticBuffer[1024];
|
||||||
|
byte* buffer = staticBuffer;
|
||||||
|
#ifdef CYASSL_SHA512
|
||||||
|
byte Ai[SHA512_DIGEST_SIZE];
|
||||||
|
byte B[SHA512_BLOCK_SIZE];
|
||||||
|
#else
|
||||||
|
byte Ai[SHA256_DIGEST_SIZE];
|
||||||
|
byte B[SHA256_BLOCK_SIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!iterations)
|
||||||
|
iterations = 1;
|
||||||
|
|
||||||
|
if (hashType == MD5) {
|
||||||
|
v = MD5_BLOCK_SIZE;
|
||||||
|
u = MD5_DIGEST_SIZE;
|
||||||
|
}
|
||||||
|
else if (hashType == SHA) {
|
||||||
|
v = SHA_BLOCK_SIZE;
|
||||||
|
u = SHA_DIGEST_SIZE;
|
||||||
|
}
|
||||||
|
else if (hashType == SHA256) {
|
||||||
|
v = SHA256_BLOCK_SIZE;
|
||||||
|
u = SHA256_DIGEST_SIZE;
|
||||||
|
}
|
||||||
|
#ifdef CYASSL_SHA512
|
||||||
|
else if (hashType == SHA512) {
|
||||||
|
v = SHA512_BLOCK_SIZE;
|
||||||
|
u = SHA512_DIGEST_SIZE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
return -1; /* bad hashType */
|
||||||
|
|
||||||
|
dLen = v;
|
||||||
|
sLen = v * ((saltLen + v - 1) / v);
|
||||||
|
if (passLen)
|
||||||
|
pLen = v * ((passLen + v - 1) / v);
|
||||||
|
else
|
||||||
|
pLen = 0;
|
||||||
|
iLen = sLen + pLen;
|
||||||
|
|
||||||
|
totalLen = dLen + sLen + pLen;
|
||||||
|
|
||||||
|
if (totalLen > sizeof(staticBuffer)) {
|
||||||
|
buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
|
||||||
|
if (buffer == NULL) return -1;
|
||||||
|
dynamic = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
D = buffer;
|
||||||
|
S = D + dLen;
|
||||||
|
P = S + sLen;
|
||||||
|
I = S;
|
||||||
|
|
||||||
|
XMEMSET(D, id, dLen);
|
||||||
|
|
||||||
|
for (i = 0; i < sLen; i++)
|
||||||
|
S[i] = salt[i % saltLen];
|
||||||
|
for (i = 0; i < pLen; i++)
|
||||||
|
P[i] = passwd[i % passLen];
|
||||||
|
|
||||||
|
while (kLen > 0) {
|
||||||
|
word32 currentLen;
|
||||||
|
mp_int B1;
|
||||||
|
|
||||||
|
if (hashType == MD5) {
|
||||||
|
}
|
||||||
|
else if (hashType == SHA) {
|
||||||
|
Sha sha;
|
||||||
|
|
||||||
|
InitSha(&sha);
|
||||||
|
ShaUpdate(&sha, buffer, totalLen);
|
||||||
|
ShaFinal(&sha, Ai);
|
||||||
|
|
||||||
|
for (i = 1; i < iterations; i++) {
|
||||||
|
ShaUpdate(&sha, Ai, u);
|
||||||
|
ShaFinal(&sha, Ai);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (hashType == SHA256) {
|
||||||
|
}
|
||||||
|
#ifdef CYASSL_SHA512
|
||||||
|
else if (hashType == SHA512) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < v; i++)
|
||||||
|
B[i] = Ai[i % u];
|
||||||
|
|
||||||
|
mp_init(&B1);
|
||||||
|
if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
|
||||||
|
ret = -1;
|
||||||
|
else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY) {
|
||||||
|
ret = -1;
|
||||||
|
mp_clear(&B1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < iLen; i += v) {
|
||||||
|
int outSz;
|
||||||
|
mp_int i1;
|
||||||
|
mp_int res;
|
||||||
|
|
||||||
|
mp_init(&i1);
|
||||||
|
mp_init(&res);
|
||||||
|
|
||||||
|
if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
|
||||||
|
ret = -1;
|
||||||
|
else if (mp_add(&i1, &B1, &res) != MP_OKAY)
|
||||||
|
ret = -1;
|
||||||
|
else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
|
||||||
|
ret = -1;
|
||||||
|
else {
|
||||||
|
if (outSz > v) {
|
||||||
|
/* take off MSB */
|
||||||
|
byte tmp[129];
|
||||||
|
mp_to_unsigned_bin(&res, tmp);
|
||||||
|
XMEMCPY(I + i, tmp + 1, v);
|
||||||
|
}
|
||||||
|
else if (outSz < v) {
|
||||||
|
XMEMSET(I + i, 0, v - outSz);
|
||||||
|
mp_to_unsigned_bin(&res, I + i + v - outSz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mp_to_unsigned_bin(&res, I + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_clear(&i1);
|
||||||
|
mp_clear(&res);
|
||||||
|
if (ret < 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLen = min(kLen, u);
|
||||||
|
XMEMCPY(output, Ai, currentLen);
|
||||||
|
output += currentLen;
|
||||||
|
kLen -= currentLen;
|
||||||
|
mp_clear(&B1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* NO_PWDBASED */
|
#endif /* NO_PWDBASED */
|
||||||
|
|
||||||
|
@@ -2302,11 +2302,7 @@ void fp_gcd(fp_int *a, fp_int *b, fp_int *c)
|
|||||||
#endif /* CYASSL_KEY_GEN */
|
#endif /* CYASSL_KEY_GEN */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#if defined(HAVE_ECC) || !defined(NO_PWDBASED)
|
||||||
|
|
||||||
/* chars used in radix conversions */
|
|
||||||
const char *fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
|
|
||||||
|
|
||||||
/* c = a + b */
|
/* c = a + b */
|
||||||
void fp_add_d(fp_int *a, fp_digit b, fp_int *c)
|
void fp_add_d(fp_int *a, fp_digit b, fp_int *c)
|
||||||
{
|
{
|
||||||
@@ -2315,6 +2311,20 @@ void fp_add_d(fp_int *a, fp_digit b, fp_int *c)
|
|||||||
fp_add(a,&tmp,c);
|
fp_add(a,&tmp,c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* external compatibility */
|
||||||
|
int mp_add_d(fp_int *a, fp_digit b, fp_int *c)
|
||||||
|
{
|
||||||
|
fp_add_d(a, b, c);
|
||||||
|
return MP_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_ECC || !NO_PWDBASED */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
|
||||||
|
/* chars used in radix conversions */
|
||||||
|
const char *fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
|
||||||
|
|
||||||
int fp_read_radix(fp_int *a, const char *str, int radix)
|
int fp_read_radix(fp_int *a, const char *str, int radix)
|
||||||
{
|
{
|
||||||
|
@@ -1647,6 +1647,48 @@ int openssl_test()
|
|||||||
|
|
||||||
#ifndef NO_PWDBASED
|
#ifndef NO_PWDBASED
|
||||||
|
|
||||||
|
int pkcs12_test()
|
||||||
|
{
|
||||||
|
const byte passwd[] = { 0x00, 0x73, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x67,
|
||||||
|
0x00, 0x00 };
|
||||||
|
const byte salt[] = { 0x0a, 0x58, 0xCF, 0x64, 0x53, 0x0d, 0x82, 0x3f };
|
||||||
|
|
||||||
|
const byte passwd2[] = { 0x00, 0x71, 0x00, 0x75, 0x00, 0x65, 0x00, 0x65,
|
||||||
|
0x00, 0x67, 0x00, 0x00 };
|
||||||
|
const byte salt2[] = { 0x16, 0x82, 0xC0, 0xfC, 0x5b, 0x3f, 0x7e, 0xc5 };
|
||||||
|
byte derived[64];
|
||||||
|
|
||||||
|
const byte verify[] = {
|
||||||
|
0x8A, 0xAA, 0xE6, 0x29, 0x7B, 0x6C, 0xB0, 0x46,
|
||||||
|
0x42, 0xAB, 0x5B, 0x07, 0x78, 0x51, 0x28, 0x4E,
|
||||||
|
0xB7, 0x12, 0x8F, 0x1A, 0x2A, 0x7F, 0xBC, 0xA3
|
||||||
|
};
|
||||||
|
|
||||||
|
const byte verify2[] = {
|
||||||
|
0x48, 0x3D, 0xD6, 0xE9, 0x19, 0xD7, 0xDE, 0x2E,
|
||||||
|
0x8E, 0x64, 0x8B, 0xA8, 0xF8, 0x62, 0xF3, 0xFB,
|
||||||
|
0xFB, 0xDC, 0x2B, 0xCB, 0x2C, 0x02, 0x95, 0x7F
|
||||||
|
};
|
||||||
|
|
||||||
|
int id = 1;
|
||||||
|
int kLen = 24;
|
||||||
|
int iterations = 1;
|
||||||
|
int ret = PKCS12_PBKDF(derived, passwd, sizeof(passwd), salt, 8, iterations,
|
||||||
|
kLen, SHA, id);
|
||||||
|
|
||||||
|
if ( (ret = memcmp(derived, verify, kLen)) != 0)
|
||||||
|
return -103;
|
||||||
|
|
||||||
|
iterations = 1000;
|
||||||
|
ret = PKCS12_PBKDF(derived, passwd2, sizeof(passwd2), salt2, 8, iterations,
|
||||||
|
kLen, SHA, id);
|
||||||
|
if ( (ret = memcmp(derived, verify2, 24)) != 0)
|
||||||
|
return -104;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int pbkdf2_test()
|
int pbkdf2_test()
|
||||||
{
|
{
|
||||||
char passwd[] = "password";
|
char passwd[] = "password";
|
||||||
@@ -1665,7 +1707,7 @@ int pbkdf2_test()
|
|||||||
SHA);
|
SHA);
|
||||||
|
|
||||||
if (memcmp(derived, verify, sizeof(verify)) != 0)
|
if (memcmp(derived, verify, sizeof(verify)) != 0)
|
||||||
return -101;
|
return -102;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1697,7 +1739,9 @@ int pbkdf1_test()
|
|||||||
int pwdbased_test()
|
int pwdbased_test()
|
||||||
{
|
{
|
||||||
int ret = pbkdf1_test();
|
int ret = pbkdf1_test();
|
||||||
return ret + pbkdf2_test();
|
ret += pbkdf2_test();
|
||||||
|
|
||||||
|
return ret + pkcs12_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* NO_PWDBASED */
|
#endif /* NO_PWDBASED */
|
||||||
|
@@ -182,11 +182,16 @@ static INLINE void showPeer(SSL* ssl)
|
|||||||
subject);
|
subject);
|
||||||
ret = CyaSSL_X509_get_serial_number(peer, serial, &sz);
|
ret = CyaSSL_X509_get_serial_number(peer, serial, &sz);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
int i;
|
int i;
|
||||||
printf(" serial number");
|
int strLen;
|
||||||
|
char serialMsg[80];
|
||||||
|
|
||||||
|
/* testsuite has multiple threads writing to stdout, get output
|
||||||
|
message ready to write once */
|
||||||
|
strLen = snprintf(serialMsg, 16, " serial number");
|
||||||
for (i = 0; i < sz; i++)
|
for (i = 0; i < sz; i++)
|
||||||
printf(":%02x", serial[i]);
|
snprintf(serialMsg + strLen + (i*3), 4, ":%02x ", serial[i]);
|
||||||
printf("\n");
|
printf("%s\n", serialMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
|
XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
|
||||||
|
@@ -1348,7 +1348,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX* ctx, const char* list)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_PSK
|
#ifndef NO_PSK
|
||||||
havePSK = ssl->optoins.havePSK;
|
havePSK = ssl->options.havePSK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ssl->options.side != SERVER_END) {
|
if (ssl->options.side != SERVER_END) {
|
||||||
|
Reference in New Issue
Block a user