#include "lib6.h" #include "lib5.h" #include "lib4.h" #include "lib3.h" #include "lib2.h" #include "lib.h" #include int rsa_sign_bignum(BIGNUM *message, BIGNUM *signed_message, struct rsa_key_bignum *private) { rsa_encrypt_bignum(message, signed_message, private); } int rsa_verify_bignum(BIGNUM *signed_message, BIGNUM *org_message, struct rsa_key_bignum *public) { BIGNUM *res = BN_new(); int ret = -1; rsa_decrypt_bignum(signed_message, res, public); ret = BN_cmp(res, org_message); printf("\nverfied mess ret: %i, message:\n", ret); BN_print(out, res); printf("\n"); BN_free(res); return ret == 0; } /** * construct a VALID pkcs_padding **/ void pkcs1_5_padding(char *message, char *result, unsigned int target_length_byte) { SHA1Context sha1; char sha1_hash[20]; int i; memset(result, 0xff, target_length_byte); result[0] = 0x00; result[1] = 0x01; result[target_length_byte-21] = 0x00; // TODO ASN.1 things SHA1Reset(&sha1); SHA1Input(&sha1, message, strlen(message)); SHA1Result(&sha1); memcpy(sha1_hash, &(sha1.Message_Digest), 20); for(i = 20;i>0;i--) result[target_length_byte-i] = sha1_hash[20-i]; } int pkcs1_5_padding_verify(char *to_verify, int len, char *message) { char result[1024/8]; int i; // construct the padding how the expect it and than compare pkcs1_5_padding(message, result, 1024/8); // printf both paddings char buf[(1024/8)*2]; hex_binary_to_string(result, buf, 1024/8); printf("expected padding:\n%s\n", buf); hex_binary_to_string(to_verify, buf, len); printf("got:\n%s\n", buf); return memcmp(to_verify, result, 128) == 0; } int shitty_pkcs1_5_padding_verify(char *to_verify, int len, char *message) { int i = 2; SHA1Context sha1; char sha1_hash[20]; if (len < 2 && to_verify[0] != 0x00 && to_verify[1] != 0x01) return 0; // search for the next 0x00 no matter what's in between while(to_verify[i] != 0x00) i++; i++; // TODO check asn.1 things // verfiy the hash SHA1Reset(&sha1); SHA1Input(&sha1, message, strlen(message)); SHA1Result(&sha1); memcpy(sha1_hash, &(sha1.Message_Digest), 20); int j; for(j=0;j<20;j++, i++) { if (to_verify[i] != sha1_hash[j]) return 0; } return 1; } void init_dsa_pub_param(struct dsa_public_params *p) { char *p_str = "800000000000000089e1855218a0e7dac38136ffafa72eda7" "859f2171e25e65eac698c1702578b07dc2a1076da241c76c6" "2d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebe" "ac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2" "b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc87" "1a584471bb1"; char *q_str = "f4f47f05794b256174bba6e9b396a7707e563c5b"; char *g_str = "5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119" "458fef538b8fa4046c8db53039db620c094c9fa077ef389b5" "322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a047" "0f5b64c36b625a097f1651fe775323556fe00b3608c887892" "878480e99041be601a62166ca6894bdd41a7054ec89f756ba" "9fc95302291"; p->p = BN_new(); p->q = BN_new(); p->g = BN_new(); BN_hex2bn(&p->p, p_str); BN_hex2bn(&p->q, q_str); BN_hex2bn(&p->g, g_str); p->bits = BN_num_bytes(p->q)*16; } void dsa_compute_per_user_keys(struct dsa_public_params *pub_param, struct dsa_per_user_param *priv_param) { BN_pseudo_rand(priv_param->private, pub_param->bits, -1, -1); BN_mod(priv_param->private, priv_param->private, pub_param->q, ctx); BN_mod_exp(priv_param->public, pub_param->g, priv_param->private, pub_param->p, ctx); } void dsa_sign(char *mess, struct dsa_public_params *pub_param, struct dsa_per_user_param *priv_param, BIGNUM *k) { // random per message value BIGNUM *k_1 = BN_new(); BIGNUM *hash_bn = BN_new(); BIGNUM *tmp = BN_new(); SHA_CTX sha1; char sha1_hash[20]; SHA1_Init(&sha1); SHA1_Update(&sha1, mess, strlen(mess)); SHA1_Final(sha1_hash, &sha1); BN_bin2bn(sha1_hash, 20, hash_bn); BN_zero(priv_param->r); BN_zero(priv_param->s); while(BN_is_zero(priv_param->r) || BN_is_zero(priv_param->s)) { if(BN_is_zero(k)) { BN_pseudo_rand(k, pub_param->bits, -1, -1); BN_mod(k, k, pub_param->q, ctx); } BN_mod_exp(priv_param->r, pub_param->g, k, pub_param->p, ctx); BN_mod(priv_param->r, priv_param->r, pub_param->q, ctx); BN_mod_mul(tmp, priv_param->private, priv_param->r, pub_param->q, ctx); BN_mod_add(tmp, hash_bn, tmp, pub_param->q, ctx); BN_mod_inverse(k_1, k, pub_param->q, ctx); BN_mod_mul(priv_param->s, k_1, tmp, pub_param->q, ctx); } } int dsa_verify(char *mess, struct dsa_public_params *pub, struct dsa_per_user_param *priv) { SHA_CTX sha1; char sha1_hash[20]; BIGNUM *w = BN_new(); BIGNUM *u1 = BN_new(); BIGNUM *u2 = BN_new(); BIGNUM *tmp1 = BN_new(); BIGNUM *tmp2 = BN_new(); BIGNUM *v = BN_new(); BIGNUM *hash_bn = BN_new(); BN_mod_inverse(w, priv->s, pub->q, ctx); SHA1_Init(&sha1); SHA1_Update(&sha1, mess, strlen(mess)); SHA1_Final(sha1_hash, &sha1); BN_bin2bn(sha1_hash, 20, hash_bn); BN_mod_mul(u1, w, hash_bn, pub->q, ctx); BN_mod_mul(u2, priv->r, w, pub->q, ctx); BN_mod_exp(tmp1, pub->g, u1, pub->p, ctx); BN_mod_exp(tmp2, priv->public, u2, pub->p, ctx); BN_mod_mul(v, tmp1, tmp2, pub->p, ctx); BN_mod(v, v, pub->q, ctx); return BN_cmp(v, priv->r); } void dsa_recover_x_from_known_k(struct dsa_public_params *pub, BIGNUM *k, struct dsa_per_user_param *priv, BIGNUM *mess_hash) { BIGNUM *r_1 = BN_new(); BN_mod_inverse(r_1, priv->r, pub->q, ctx); BN_mod_mul(priv->private, k, priv->s, pub->q, ctx); BN_mod_sub(priv->private, priv->private, mess_hash, pub->q, ctx); BN_mod_mul(priv->private, priv->private, r_1, pub->q, ctx); } void dsa_recover_k_from_repeated_nonce(BIGNUM *mess1_hash, BIGNUM *mess2_hash, BIGNUM *s1, BIGNUM *s2, struct dsa_public_params *pub, struct dsa_per_user_param *priv, BIGNUM *k) { BIGNUM *diff1 = BN_new(); BN_mod_sub(diff1, mess1_hash, mess2_hash, pub->q, ctx); BN_mod_sub(k, s1, s2, pub->q, ctx); BN_mod_inverse(k, k, pub->q, ctx); BN_mod_mul(k, k, diff1, pub->q, ctx); printf("recoverd k is: \n"); BN_print(out, k); }