Import code from previous AssetBuilder version

This commit is contained in:
Jan
2019-09-24 10:45:09 +02:00
parent 5609557516
commit 0d8432d4f7
919 changed files with 154412 additions and 26 deletions

View File

@ -0,0 +1,187 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file pkcs_5_1.c
PKCS #5, Algorithm #1, Tom St Denis
*/
#ifdef LTC_PKCS_5
/**
Execute PKCS #5 v1 in strict or OpenSSL EVP_BytesToKey()-compat mode.
PKCS#5 v1 specifies that the output key length can be no larger than
the hash output length. OpenSSL unilaterally extended that by repeating
the hash process on a block-by-block basis for as long as needed to make
bigger keys. If you want to be compatible with KDF for e.g. "openssl enc",
you'll want that.
If you want strict PKCS behavior, turn openssl_compat off. Or (more
likely), use one of the convenience functions below.
@param password The password (or key)
@param password_len The length of the password (octet)
@param salt The salt (or nonce) which is 8 octets long
@param iteration_count The PKCS #5 v1 iteration count
@param hash_idx The index of the hash desired
@param out [out] The destination for this algorithm
@param outlen [in/out] The max size and resulting size of the algorithm output
@param openssl_compat [in] Whether or not to grow the key to the buffer size ala OpenSSL
@return CRYPT_OK if successful
*/
static int _pkcs_5_alg1_common(const unsigned char *password,
unsigned long password_len,
const unsigned char *salt,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen,
int openssl_compat)
{
int err;
unsigned long x;
hash_state *md;
unsigned char *buf;
/* Storage vars in case we need to support > hashsize (OpenSSL compat) */
unsigned long block = 0, iter;
/* How many bytes to put in the outbut buffer (convenience calc) */
unsigned long outidx = 0, nb = 0;
LTC_ARGCHK(password != NULL);
LTC_ARGCHK(salt != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* test hash IDX */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* allocate memory */
md = XMALLOC(sizeof(hash_state));
buf = XMALLOC(MAXBLOCKSIZE);
if (md == NULL || buf == NULL) {
if (md != NULL) {
XFREE(md);
}
if (buf != NULL) {
XFREE(buf);
}
return CRYPT_MEM;
}
while(block * hash_descriptor[hash_idx].hashsize < *outlen) {
/* hash initial (maybe previous hash) + password + salt */
if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
goto LBL_ERR;
}
/* in OpenSSL mode, we first hash the previous result for blocks 2-n */
if (openssl_compat && block) {
if ((err = hash_descriptor[hash_idx].process(md, buf, hash_descriptor[hash_idx].hashsize)) != CRYPT_OK) {
goto LBL_ERR;
}
}
if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
goto LBL_ERR;
}
iter = iteration_count;
while (--iter) {
/* code goes here. */
x = MAXBLOCKSIZE;
if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
}
/* limit the size of the copy to however many bytes we have left in
the output buffer (and how many bytes we have to copy) */
outidx = block*hash_descriptor[hash_idx].hashsize;
nb = hash_descriptor[hash_idx].hashsize;
if(outidx+nb > *outlen)
nb = *outlen - outidx;
if(nb > 0)
XMEMCPY(out+outidx, buf, nb);
block++;
if (!openssl_compat)
break;
}
/* In strict mode, we always return the hashsize, in compat we filled it
as much as was requested, so we leave it alone. */
if(!openssl_compat)
*outlen = hash_descriptor[hash_idx].hashsize;
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(buf, MAXBLOCKSIZE);
zeromem(md, sizeof(hash_state));
#endif
XFREE(buf);
XFREE(md);
return err;
}
/**
Execute PKCS #5 v1 - Strict mode (no OpenSSL-compatible extension)
@param password The password (or key)
@param password_len The length of the password (octet)
@param salt The salt (or nonce) which is 8 octets long
@param iteration_count The PKCS #5 v1 iteration count
@param hash_idx The index of the hash desired
@param out [out] The destination for this algorithm
@param outlen [in/out] The max size and resulting size of the algorithm output
@return CRYPT_OK if successful
*/
int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
const unsigned char *salt,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
return _pkcs_5_alg1_common(password, password_len, salt, iteration_count,
hash_idx, out, outlen, 0);
}
/**
Execute PKCS #5 v1 - OpenSSL-extension-compatible mode
Use this one if you need to derive keys as "openssl enc" does by default.
OpenSSL (for better or worse), uses MD5 as the hash and iteration_count=1.
@param password The password (or key)
@param password_len The length of the password (octet)
@param salt The salt (or nonce) which is 8 octets long
@param iteration_count The PKCS #5 v1 iteration count
@param hash_idx The index of the hash desired
@param out [out] The destination for this algorithm
@param outlen [in/out] The max size and resulting size of the algorithm output
@return CRYPT_OK if successful
*/
int pkcs_5_alg1_openssl(const unsigned char *password,
unsigned long password_len,
const unsigned char *salt,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
return _pkcs_5_alg1_common(password, password_len, salt, iteration_count,
hash_idx, out, outlen, 1);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@ -0,0 +1,127 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file pkcs_5_2.c
PKCS #5, Algorithm #2, Tom St Denis
*/
#ifdef LTC_PKCS_5
/**
Execute PKCS #5 v2
@param password The input password (or key)
@param password_len The length of the password (octets)
@param salt The salt (or nonce)
@param salt_len The length of the salt (octets)
@param iteration_count # of iterations desired for PKCS #5 v2 [read specs for more]
@param hash_idx The index of the hash desired
@param out [out] The destination for this algorithm
@param outlen [in/out] The max size and resulting size of the algorithm output
@return CRYPT_OK if successful
*/
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
int err, itts;
ulong32 blkno;
unsigned long stored, left, x, y;
unsigned char *buf[2];
hmac_state *hmac;
LTC_ARGCHK(password != NULL);
LTC_ARGCHK(salt != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* test hash IDX */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
hmac = XMALLOC(sizeof(hmac_state));
if (hmac == NULL || buf[0] == NULL) {
if (hmac != NULL) {
XFREE(hmac);
}
if (buf[0] != NULL) {
XFREE(buf[0]);
}
return CRYPT_MEM;
}
/* buf[1] points to the second block of MAXBLOCKSIZE bytes */
buf[1] = buf[0] + MAXBLOCKSIZE;
left = *outlen;
blkno = 1;
stored = 0;
while (left != 0) {
/* process block number blkno */
zeromem(buf[0], MAXBLOCKSIZE*2);
/* store current block number and increment for next pass */
STORE32H(blkno, buf[1]);
++blkno;
/* get PRF(P, S||int(blkno)) */
if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
goto LBL_ERR;
}
x = MAXBLOCKSIZE;
if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
goto LBL_ERR;
}
/* now compute repeated and XOR it in buf[1] */
XMEMCPY(buf[1], buf[0], x);
for (itts = 1; itts < iteration_count; ++itts) {
if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
goto LBL_ERR;
}
for (y = 0; y < x; y++) {
buf[1][y] ^= buf[0][y];
}
}
/* now emit upto x bytes of buf[1] to output */
for (y = 0; y < x && left != 0; ++y) {
out[stored++] = buf[1][y];
--left;
}
}
*outlen = stored;
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(buf[0], MAXBLOCKSIZE*2);
zeromem(hmac, sizeof(hmac_state));
#endif
XFREE(hmac);
XFREE(buf[0]);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@ -0,0 +1,231 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file hkdf_test.c
PKCS #5 support, self-test, Steffen Jaeckel
*/
#ifdef LTC_PKCS_5
/*
TEST CASES SOURCE:
Internet Engineering Task Force (IETF) S. Josefsson
Request for Comments: 6070 SJD AB
Category: Informational January 2011
ISSN: 2070-1721
*/
/**
PKCS #5 self-test
@return CRYPT_OK if successful, CRYPT_NOP if tests have been disabled.
*/
int pkcs_5_test (void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
typedef struct {
const char* P;
unsigned long P_len;
const char* S;
unsigned long S_len;
int c;
unsigned long dkLen;
unsigned char DK[40];
} case_item;
static const case_item cases_5_2[] = {
{
"password",
8,
"salt",
4,
1,
20,
{ 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
0x2f, 0xe0, 0x37, 0xa6 }
},
{
"password",
8,
"salt",
4,
2,
20,
{ 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
0xd8, 0xde, 0x89, 0x57 }
},
#ifdef LTC_TEST_EXT
{
"password",
8,
"salt",
4,
4096,
20,
{ 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
0x65, 0xa4, 0x29, 0xc1 }
},
{
"password",
8,
"salt",
4,
16777216,
20,
{ 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
0x26, 0x34, 0xe9, 0x84 }
},
{
"passwordPASSWORDpassword",
25,
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
36,
4096,
25,
{ 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
0x38 }
},
{
"pass\0word",
9,
"sa\0lt",
5,
4096,
16,
{ 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 }
},
#endif /* LTC_TEST_EXT */
};
static const case_item cases_5_1[] = {
{
"password",
8,
"saltsalt", /* must be 8 octects */
8, /* ignored by alg1 */
1,
20,
{ 0xca, 0xb8, 0x6d, 0xd6, 0x26, 0x17, 0x10, 0x89, 0x1e, 0x8c,
0xb5, 0x6e, 0xe3, 0x62, 0x56, 0x91, 0xa7, 0x5d, 0xf3, 0x44 }
},
};
static const case_item cases_5_1o[] = {
{
"password",
8,
"saltsalt", /* must be 8 octects */
8, /* ignored by alg1_openssl */
1,
20,
{ 0xca, 0xb8, 0x6d, 0xd6, 0x26, 0x17, 0x10, 0x89, 0x1e, 0x8c,
0xb5, 0x6e, 0xe3, 0x62, 0x56, 0x91, 0xa7, 0x5d, 0xf3, 0x44 }
},
{
"password",
8,
"saltsalt", /* must be 8 octects */
8, /* ignored by alg1_openssl */
1,
30,
{ 0xca, 0xb8, 0x6d, 0xd6, 0x26, 0x17, 0x10, 0x89, 0x1e, 0x8c,
0xb5, 0x6e, 0xe3, 0x62, 0x56, 0x91, 0xa7, 0x5d, 0xf3, 0x44,
0xf0, 0xbf, 0xf4, 0xc1, 0x2c, 0xf3, 0x59, 0x6f, 0xc0, 0x0b }
}
};
unsigned char DK[40];
unsigned long dkLen;
int i, err;
int tested=0, failed=0;
int hash = find_hash("sha1");
if (hash == -1)
{
#ifdef LTC_TEST_DBG
printf("PKCS#5 test failed: 'sha1' hash not found\n");
#endif
return CRYPT_ERROR;
}
/* testing alg 2 */
for(i=0; i < (int)(sizeof(cases_5_2) / sizeof(cases_5_2[0])); i++) {
++tested;
dkLen = cases_5_2[i].dkLen;
if((err = pkcs_5_alg2((unsigned char*)cases_5_2[i].P, cases_5_2[i].P_len,
(unsigned char*)cases_5_2[i].S, cases_5_2[i].S_len,
cases_5_2[i].c, hash,
DK, &dkLen)) != CRYPT_OK) {
#ifdef LTC_TEST_DBG
printf("\npkcs_5_alg2() #%d: Failed/1 (%s)\n", i, error_to_string(err));
#endif
++failed;
}
else if (compare_testvector(DK, dkLen, cases_5_2[i].DK, cases_5_2[i].dkLen, "PKCS#5_2", i)) {
++failed;
}
}
/* testing alg 1 */
for(i=0; i < (int)(sizeof(cases_5_1) / sizeof(case_item)); i++, tested++) {
dkLen = cases_5_1[i].dkLen;
if((err = pkcs_5_alg1((unsigned char*)cases_5_1[i].P, cases_5_1[i].P_len,
(unsigned char*)cases_5_1[i].S,
cases_5_1[i].c, hash,
DK, &dkLen)) != CRYPT_OK) {
#ifdef LTC_TEST_DBG
printf("\npkcs_5_alg1() #%d: Failed/1 (%s)\n", i, error_to_string(err));
#endif
++failed;
}
else if (compare_testvector(DK, dkLen, cases_5_1[i].DK, cases_5_1[i].dkLen, "PKCS#5_1", i)) {
++failed;
}
}
/* testing alg 1_openssl */
for(i = 0; i < (int)(sizeof(cases_5_1o) / sizeof(cases_5_1o[0])); i++, tested++) {
dkLen = cases_5_1o[i].dkLen;
if ((err = pkcs_5_alg1_openssl((unsigned char*)cases_5_1o[i].P, cases_5_1o[i].P_len,
(unsigned char*)cases_5_1o[i].S,
cases_5_1o[i].c, hash,
DK, &dkLen)) != CRYPT_OK) {
#ifdef LTC_TEST_DBG
printf("\npkcs_5_alg1_openssl() #%d: Failed/1 (%s)\n", i, error_to_string(err));
#endif
++failed;
}
else if (compare_testvector(DK, dkLen, cases_5_1o[i].DK, cases_5_1o[i].dkLen, "PKCS#5_1o", i)) {
++failed;
}
}
return (failed != 0) ? CRYPT_FAIL_TESTVECTOR : CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */