Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions demos/timing.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,11 +702,21 @@ static void time_rsa(void)
unsigned char buf[2][2048] = { 0 };
unsigned long x, y, z, zzz;
int err, zz, stat;
ltc_rsa_op_parameters rsa_params = {
.u.crypt.lparam = (const unsigned char *)"testprog",
.u.crypt.lparamlen = 8,
.prng = &yarrow_prng,
.wprng = find_prng("yarrow"),
.params.hash_alg = "sha1",
.params.mgf1_hash_alg = "sha1",
.params.saltlen = 8,
};

if (ltc_mp.name == NULL) return;

for (x = 2048; x <= 8192; x <<= 1) {
t2 = 0;
rsa_params.padding = LTC_PKCS_1_OAEP;
for (y = 0; y < 4; y++) {
t_start();
t1 = t_read();
Expand Down Expand Up @@ -734,9 +744,7 @@ static void time_rsa(void)
t_start();
t1 = t_read();
z = sizeof(buf[1]);
if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng,
find_prng("yarrow"), find_hash("sha1"),
&key)) != CRYPT_OK) {
if ((err = rsa_encrypt_key_v2(buf[0], 32, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand All @@ -755,8 +763,7 @@ static void time_rsa(void)
t_start();
t1 = t_read();
zzz = sizeof(buf[0]);
if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"),
&zz, &key)) != CRYPT_OK) {
if ((err = rsa_decrypt_key_v2(buf[1], z, buf[0], &zzz, &rsa_params, &zz, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand All @@ -771,12 +778,12 @@ static void time_rsa(void)
fprintf(stderr, "RSA-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2);

t2 = 0;
rsa_params.padding = LTC_PKCS_1_PSS;
for (y = 0; y < 256; y++) {
t_start();
t1 = t_read();
z = sizeof(buf[1]);
if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) {
if ((err = rsa_sign_hash_v2(buf[0], 20, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand All @@ -794,7 +801,7 @@ static void time_rsa(void)
for (y = 0; y < 2048; y++) {
t_start();
t1 = t_read();
if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) {
if ((err = rsa_verify_hash_v2(buf[1], z, buf[0], 20, &rsa_params, &stat, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand Down
692 changes: 461 additions & 231 deletions doc/crypt.tex

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/headers/tomcrypt_custom.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,10 @@
/* Maximum recursion limit when processing nested ASN.1 types. */
#define LTC_DER_MAX_RECURSION 30
#endif
#ifndef LTC_DER_OID_DEFAULT_NODES
/* Default number of nodes when decoding an OID. */
#define LTC_DER_OID_DEFAULT_NODES 12
#endif
#endif

#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_SSH)
Expand Down
142 changes: 121 additions & 21 deletions src/headers/tomcrypt_pk.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum ltc_pka_id {
LTC_PKA_X25519,
LTC_PKA_ED25519,
LTC_PKA_DH,
LTC_PKA_RSA_PSS,
LTC_PKA_NUM
};

Expand All @@ -62,7 +63,21 @@ int rand_prime(void *N, long len, prng_state *prng, int wprng);
/* ---- RSA ---- */
#ifdef LTC_MRSA

/** RSA PKCS style key */
typedef struct ltc_rsa_parameters {
/** PSS/OAEP or PKCS #1 v1.5 style
* 0 -> PKCS #1 v1.5, 1 -> PSS/OAEP */
int pss_oaep;
/** saltLength is only defined for PSS
* If saltLength == 0 -> OAEP, else -> PSS */
unsigned long saltlen;
/** lparam hash for OAEP
* resp.
* signature hash for PSS
* and MGF hash algorithms */
const char *hash_alg, *mgf1_hash_alg;
} ltc_rsa_parameters;

/** RSA key */
typedef struct Rsa_key {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
Expand All @@ -82,6 +97,8 @@ typedef struct Rsa_key {
void *dP;
/** The d mod (q - 1) CRT param */
void *dQ;
/** Further parameters of the RSA key */
ltc_rsa_parameters params;
} rsa_key;

int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
Expand All @@ -95,50 +112,133 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,

void rsa_free(rsa_key *key);

/* These use PKCS #1 v2.0 padding */
#define rsa_encrypt_key(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, key) \
rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, -1, LTC_PKCS_1_OAEP, key)

#define rsa_decrypt_key(in, inlen, out, outlen, lparam, lparamlen, hash_idx, stat, key) \
rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, -1, LTC_PKCS_1_OAEP, stat, key)

#define rsa_sign_hash(in, inlen, out, outlen, prng, prng_idx, hash_idx, saltlen, key) \
rsa_sign_hash_ex(in, inlen, out, outlen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key)

#define rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx, saltlen, stat, key) \
rsa_verify_hash_ex(sig, siglen, hash, hashlen, LTC_PKCS_1_PSS, hash_idx, saltlen, stat, key)

#define rsa_sign_saltlen_get_max(hash_idx, key) \
rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key)
typedef struct ltc_rsa_op_parameters {
/* The RSA API will set the `pss_oaep` field for you,
* depending on the value of `padding`. */
ltc_rsa_parameters params;
/* The padding type */
int padding;
/* The PRNG to use.
* Only required for signing and encryption. */
int wprng;
prng_state *prng;
/* Operation-specific parameters */
union {
struct {
const unsigned char *lparam;
unsigned long lparamlen;
} crypt;
/* let's make space for potential future extensions */
ulong64 dummy[8];
} u;
} ltc_rsa_op_parameters;

int rsa_encrypt_key_v2(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
ltc_rsa_op_parameters *opts,
const rsa_key *key);

int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
ltc_rsa_op_parameters *opts,
int *stat,
const rsa_key *key);

int rsa_sign_hash_v2(const unsigned char *hash, unsigned long hashlen,
unsigned char *sig, unsigned long *siglen,
ltc_rsa_op_parameters *opts,
const rsa_key *key);

int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
ltc_rsa_op_parameters *opts,
int *stat,
const rsa_key *key);

/* These use PKCS #1 v2.0 padding */
#define ltc_rsa_encrypt_key(in, inlen, out, outlen, lp, lplen, prng_, prng_idx, hash_idx, key) \
rsa_encrypt_key_v2(in, inlen, out, outlen, \
&(ltc_rsa_op_parameters){ \
.u.crypt.lparam = lp, \
.u.crypt.lparamlen = lplen,\
.prng = prng_, \
.wprng = prng_idx, \
.params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.padding = LTC_PKCS_1_OAEP, \
}, key)

#define ltc_rsa_decrypt_key(in, inlen, out, outlen, lp, lplen, hash_idx, stat, key) \
rsa_decrypt_key_v2(in, inlen, out, outlen, \
&(ltc_rsa_op_parameters){ \
.u.crypt.lparam = lp, \
.u.crypt.lparamlen = lplen,\
.params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.padding = LTC_PKCS_1_OAEP, \
}, stat, key)

#define ltc_rsa_sign_hash(hash, hashlen, sig, siglen, prng_, prng_idx, hash_idx, saltlen_, key) \
rsa_sign_hash_v2(hash, hashlen, sig, siglen, \
&(ltc_rsa_op_parameters){ \
.prng = prng_, \
.wprng = prng_idx, \
.params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.params.saltlen = saltlen_, \
.padding = LTC_PKCS_1_PSS, \
}, key)

#define ltc_rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx, saltlen_, stat, key) \
rsa_verify_hash_v2(sig, siglen, hash, hashlen, \
&(ltc_rsa_op_parameters){ \
.params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \
.params.saltlen = saltlen_, \
.padding = LTC_PKCS_1_PSS, \
}, stat, key)

/* If you used those in v1, they're still working */
#define rsa_encrypt_key ltc_rsa_encrypt_key
#define rsa_decrypt_key ltc_rsa_decrypt_key
#define rsa_sign_hash ltc_rsa_sign_hash
#define rsa_verify_hash ltc_rsa_verify_hash

#ifndef LTC_NO_DEPRECATED_APIS
/* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */
LTC_DEPRECATED(rsa_encrypt_key_v2)
int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx,
int mgf_hash, int lparam_hash,
int padding,
int hash_idx, int padding,
const rsa_key *key);

LTC_DEPRECATED(rsa_decrypt_key_v2)
int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
int mgf_hash, int lparam_hash,
int padding,
int hash_idx, int padding,
int *stat, const rsa_key *key);

LTC_DEPRECATED(rsa_sign_hash_v2)
int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int padding,
prng_state *prng, int prng_idx,
prng_state *prng, int prng_idx,
int hash_idx, unsigned long saltlen,
const rsa_key *key);

LTC_DEPRECATED(rsa_verify_hash_v2)
int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int padding,
int hash_idx, unsigned long saltlen,
int *stat, const rsa_key *key);
#endif /* LTC_NO_DEPRECATED_APIS */

#define rsa_sign_saltlen_get_max(hash_idx, key) \
rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key)

int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, const rsa_key *key);

Expand Down
17 changes: 13 additions & 4 deletions src/headers/tomcrypt_pkcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@ enum ltc_pkcs_1_paddings
LTC_PKCS_1_V1_5_NA1 = 4 /* PKCS #1 v1.5 padding - No ASN.1 (\sa ltc_pkcs_1_v1_5_blocks) */
};

#ifndef LTC_NO_DEPRECATED_APIS
LTC_DEPRECATED(nothing. API will be internal)
int pkcs_1_mgf1( int hash_idx,
const unsigned char *seed, unsigned long seedlen,
unsigned char *mask, unsigned long masklen);

LTC_DEPRECATED(nothing. API will be removed)
int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
LTC_DEPRECATED(nothing. API will be removed)
int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen);

/* *** v1.5 padding */
LTC_DEPRECATED(nothing. API will be internal)
int pkcs_1_v1_5_encode(const unsigned char *msg,
unsigned long msglen,
int block_type,
Expand All @@ -37,6 +42,7 @@ int pkcs_1_v1_5_encode(const unsigned char *msg,
unsigned char *out,
unsigned long *outlen);

LTC_DEPRECATED(nothing. API will be internal)
int pkcs_1_v1_5_decode(const unsigned char *msg,
unsigned long msglen,
int block_type,
Expand All @@ -46,30 +52,33 @@ int pkcs_1_v1_5_decode(const unsigned char *msg,
int *is_valid);

/* *** v2.1 padding */
LTC_DEPRECATED(nothing. API will be internal)
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, prng_state *prng,
int prng_idx,
int mgf_hash, int lparam_hash,
int prng_idx, int hash_idx,
unsigned char *out, unsigned long *outlen);

LTC_DEPRECATED(nothing. API will be internal)
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen,
int mgf_hash, int lparam_hash,
unsigned long modulus_bitlen, int hash_idx,
unsigned char *out, unsigned long *outlen,
int *res);

LTC_DEPRECATED(nothing. API will be internal)
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
unsigned long saltlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned long modulus_bitlen,
unsigned char *out, unsigned long *outlen);

LTC_DEPRECATED(nothing. API will be internal)
int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
const unsigned char *sig, unsigned long siglen,
unsigned long saltlen, int hash_idx,
unsigned long modulus_bitlen, int *res);
#endif /* LTC_NO_DEPRECATED_APIS */

#endif /* LTC_PKCS_1 */

Expand Down
Loading