diff options
Diffstat (limited to 'crypto/userspace/libtomcrypt/pk/dsa')
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/dsa/dsa_export.c | 99 | ||||
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/dsa/dsa_free.c | 34 | ||||
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/dsa/dsa_import.c | 101 | ||||
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/dsa/dsa_make_key.c | 125 | ||||
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/dsa/dsa_sign_hash.c | 147 | ||||
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_hash.c | 126 | ||||
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_key.c | 100 |
7 files changed, 732 insertions, 0 deletions
diff --git a/crypto/userspace/libtomcrypt/pk/dsa/dsa_export.c b/crypto/userspace/libtomcrypt/pk/dsa/dsa_export.c new file mode 100644 index 00000000000..5a2d5df87c7 --- /dev/null +++ b/crypto/userspace/libtomcrypt/pk/dsa/dsa_export.c @@ -0,0 +1,99 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file dsa_export.c + DSA implementation, export key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Export a DSA key to a binary packet + @param out [out] Where to store the packet + @param outlen [in/out] The max size and resulting size of the packet + @param type The type of key to export (PK_PRIVATE or PK_PUBLIC) + @param key The key to export + @return CRYPT_OK if successful +*/ +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) +{ + unsigned long zero=0; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* can we store the static header? */ + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + if (type != PK_PUBLIC && type != PK_PRIVATE) { + return CRYPT_INVALID_ARG; + } + + /* This encoding is different from the one in original + * libtomcrypt. It uses a compatible encoding with gnutls + * and openssl + */ + if (type == PK_PRIVATE) { + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->g, + LTC_ASN1_INTEGER, 1UL, &key->y, + LTC_ASN1_INTEGER, 1UL, &key->x, + LTC_ASN1_EOL, 0UL, NULL); + } else { + unsigned long tmplen = (mp_count_bits(&key->y)/8)+8; + unsigned char* tmp = XMALLOC(tmplen); + ltc_asn1_list int_list[3]; + + if (tmp == NULL) { + return CRYPT_MEM; + } + + err = der_encode_integer(&key->y, tmp, &tmplen); + if (err != CRYPT_OK) { + goto error; + } + + int_list[0].data = &key->p; + int_list[0].size = 1UL; + int_list[0].type = LTC_ASN1_INTEGER; + int_list[1].data = &key->q; + int_list[1].size = 1UL; + int_list[1].type = LTC_ASN1_INTEGER; + int_list[2].data = &key->g; + int_list[2].size = 1UL; + int_list[2].type = LTC_ASN1_INTEGER; + + err = der_encode_subject_public_key_info(out, outlen, + PKA_DSA, tmp, tmplen, + LTC_ASN1_SEQUENCE, int_list, sizeof(int_list)/sizeof(int_list[0])); + +error: + XFREE(tmp); + return err; + } +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_export.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/crypto/userspace/libtomcrypt/pk/dsa/dsa_free.c b/crypto/userspace/libtomcrypt/pk/dsa/dsa_free.c new file mode 100644 index 00000000000..37a330d14e8 --- /dev/null +++ b/crypto/userspace/libtomcrypt/pk/dsa/dsa_free.c @@ -0,0 +1,34 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_free.c + DSA implementation, free a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Free a DSA key + @param key The key to free from memory +*/ +void dsa_free(dsa_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_free.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/crypto/userspace/libtomcrypt/pk/dsa/dsa_import.c b/crypto/userspace/libtomcrypt/pk/dsa/dsa_import.c new file mode 100644 index 00000000000..c6a1f6f6037 --- /dev/null +++ b/crypto/userspace/libtomcrypt/pk/dsa/dsa_import.c @@ -0,0 +1,101 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file dsa_import.c + DSA implementation, import a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Import a DSA key + @param in The binary packet to import from + @param inlen The length of the binary packet + @param key [out] Where to store the imported key + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + unsigned long zero = 0; + unsigned char* tmpbuf = NULL; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + /* init key */ + if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* get key type */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->g, + LTC_ASN1_INTEGER, 1UL, &key->y, + LTC_ASN1_INTEGER, 1UL, &key->x, + LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { + key->type = PK_PRIVATE; + } else { /* public */ + ltc_asn1_list params[3]; + unsigned long tmpbuf_len = MAX_RSA_SIZE*8; + + LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, &key->p, 1UL); + LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, &key->q, 1UL); + LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, &key->g, 1UL); + + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + err = der_decode_subject_public_key_info(in, inlen, + PKA_DSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_SEQUENCE, params, 3); + if (err != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err=der_decode_integer(tmpbuf, tmpbuf_len, &key->y)) != CRYPT_OK) { + goto LBL_ERR; + } + + XFREE(tmpbuf); + key->type = PK_PUBLIC; + } + + key->qord = mp_unsigned_bin_size(&key->q); + + if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || + (unsigned long)key->qord >= mp_unsigned_bin_size(&key->p) || (mp_unsigned_bin_size(&key->p) - key->qord) >= LTC_MDSA_DELTA) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + return CRYPT_OK; + +LBL_ERR: + XFREE(tmpbuf); + mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_import.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/crypto/userspace/libtomcrypt/pk/dsa/dsa_make_key.c b/crypto/userspace/libtomcrypt/pk/dsa/dsa_make_key.c new file mode 100644 index 00000000000..eab5d155899 --- /dev/null +++ b/crypto/userspace/libtomcrypt/pk/dsa/dsa_make_key.c @@ -0,0 +1,125 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file dsa_make_key.c + DSA implementation, generate a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Create a DSA key + @param group_size Size of the multiplicative group (octets) + @param modulus_size Size of the modulus (octets) + @param key [out] Where to store the created key + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_make_key(int group_size, int modulus_size, dsa_key *key) +{ + mp_int tmp, tmp2; + int err, res; + unsigned char *buf; + + LTC_ARGCHK(key != NULL); + + /* check size */ + if (group_size >= LTC_MDSA_MAX_GROUP || group_size <= 15 || + group_size >= modulus_size || (modulus_size - group_size) >= LTC_MDSA_DELTA) { + return CRYPT_INVALID_ARG; + } + + /* allocate ram */ + buf = XMALLOC(LTC_MDSA_DELTA); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* init mp_ints */ + if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* make our prime q */ + if ((err = rand_prime(&key->q, group_size)) != CRYPT_OK) { goto error; } + + /* double q */ + if ((err = mp_add(&key->q, &key->q, &tmp)) != CRYPT_OK) { goto error; } + + /* now make a random string and multply it against q */ + get_random_bytes(buf+1, modulus_size - group_size); + + /* force magnitude */ + buf[0] |= 0xC0; + + /* force even */ + buf[modulus_size - group_size - 1] &= ~1; + + if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; } + if ((err = mp_mul(&key->q, &tmp2, &key->p)) != CRYPT_OK) { goto error; } + if ((err = mp_add_d(&key->p, 1, &key->p)) != CRYPT_OK) { goto error; } + + /* now loop until p is prime */ + for (;;) { + if ((err = mp_prime_is_prime(&key->p, 8, &res)) != CRYPT_OK) { goto error; } + if (res == LTC_MP_YES) break; + + /* add 2q to p and 2 to tmp2 */ + if ((err = mp_add(&tmp, &key->p, &key->p)) != CRYPT_OK) { goto error; } + if ((err = mp_add_d(&tmp2, 2, &tmp2)) != CRYPT_OK) { goto error; } + } + + /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ + mp_set(&key->g, 1); + + do { + if ((err = mp_add_d(&key->g, 1, &key->g)) != CRYPT_OK) { goto error; } + if ((err = mp_exptmod(&key->g, &tmp2, &key->p, &tmp)) != CRYPT_OK) { goto error; } + } while (mp_cmp_d(&tmp, 1) == LTC_MP_EQ); + + /* at this point tmp generates a group of order q mod p */ + mp_exch(&tmp, &key->g); + + /* so now we have our DH structure, generator g, order q, modulus p + Now we need a random exponent [mod q] and it's power g^x mod p + */ + do { + get_random_bytes(buf, group_size); + + if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != CRYPT_OK) { goto error; } + } while (mp_cmp_d(&key->x, 1) != LTC_MP_GT); + if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != CRYPT_OK) { goto error; } + + key->type = PK_PRIVATE; + key->qord = group_size; + +#ifdef LTC_CLEAN_STACK + zeromem(buf, LTC_MDSA_DELTA); +#endif + + err = CRYPT_OK; + goto done; +error: + mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL); +done: + mp_clear_multi(&tmp, &tmp2, NULL); + XFREE(buf); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/crypto/userspace/libtomcrypt/pk/dsa/dsa_sign_hash.c b/crypto/userspace/libtomcrypt/pk/dsa/dsa_sign_hash.c new file mode 100644 index 00000000000..6f4dad8d3e6 --- /dev/null +++ b/crypto/userspace/libtomcrypt/pk/dsa/dsa_sign_hash.c @@ -0,0 +1,147 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file dsa_sign_hash.c + DSA implementation, sign a hash, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Sign a hash with DSA + @param in The hash to sign + @param inlen The length of the hash to sign + @param r The "r" integer of the signature (caller must initialize with mp_init() first) + @param s The "s" integer of the signature (caller must initialize with mp_init() first) + @param key A private DSA key + @return CRYPT_OK if successful +*/ +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + mp_int_t r, mp_int_t s, + dsa_key *key) +{ + mp_int k, kinv, tmp; + unsigned char *buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(key != NULL); + + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* check group order size */ + if (key->qord >= LTC_MDSA_MAX_GROUP) { + return CRYPT_INVALID_ARG; + } + + buf = XMALLOC(LTC_MDSA_MAX_GROUP); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* Init our temps */ + if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; } + +retry: + + do { + /* gen random k */ + get_random_bytes(buf, key->qord); + + /* read k */ + if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != CRYPT_OK) { goto error; } + + /* k > 1 ? */ + if (mp_cmp_d(&k, 1) != LTC_MP_GT) { goto retry; } + + /* test gcd */ + if ((err = mp_gcd(&k, &key->q, &tmp)) != CRYPT_OK) { goto error; } + } while (mp_cmp_d(&tmp, 1) != LTC_MP_EQ); + + /* now find 1/k mod q */ + if ((err = mp_invmod(&k, &key->q, &kinv)) != CRYPT_OK) { goto error; } + + /* now find r = g^k mod p mod q */ + if ((err = mp_exptmod(&key->g, &k, &key->p, r)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(r, &key->q, r)) != CRYPT_OK) { goto error; } + + if (mp_iszero(r) == LTC_MP_YES) { goto retry; } + + /* now find s = (in + xr)/k mod q */ + if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; } + if ((err = mp_mul(&key->x, r, s)) != CRYPT_OK) { goto error; } + if ((err = mp_add(s, &tmp, s)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(s, &kinv, &key->q, s)) != CRYPT_OK) { goto error; } + + if (mp_iszero(s) == LTC_MP_YES) { goto retry; } + + err = CRYPT_OK; +error: + mp_clear_multi(&k, &kinv, &tmp, NULL); +ERRBUF: +#ifdef LTC_CLEAN_STACK + zeromem(buf, LTC_MDSA_MAX_GROUP); +#endif + XFREE(buf); + return err; +} + +/** + Sign a hash with DSA + @param in The hash to sign + @param inlen The length of the hash to sign + @param out [out] Where to store the signature + @param outlen [in/out] The max size and resulting size of the signature + @param key A private DSA key + @return CRYPT_OK if successful +*/ +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dsa_key *key) +{ + mp_int r, s; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + if ((err = dsa_sign_hash_raw(in, inlen, &r, &s, key)) != CRYPT_OK) { + goto error; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, &r, + LTC_ASN1_INTEGER, 1UL, &s, + LTC_ASN1_EOL, 0UL, NULL); + +error: + mp_clear_multi(&r, &s, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_sign_hash.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_hash.c b/crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_hash.c new file mode 100644 index 00000000000..3a82d1bc420 --- /dev/null +++ b/crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_hash.c @@ -0,0 +1,126 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_verify_hash.c + DSA implementation, verify a signature, Tom St Denis +*/ + + +#ifdef LTC_MDSA + +/** + Verify a DSA signature + @param r DSA "r" parameter + @param s DSA "s" parameter + @param hash The hash that was signed + @param hashlen The length of the hash that was signed + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param key The corresponding public DH key + @return CRYPT_OK if successful (even if the signature is invalid) +*/ +int dsa_verify_hash_raw( mp_int_t r, mp_int_t s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key) +{ + mp_int w, v, u1, u2; + int err; + + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + /* init our variables */ + if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) { + return err; + } + + /* neither r or s can be null or >q*/ + if (mp_iszero(r) == LTC_MP_YES || mp_iszero(s) == LTC_MP_YES || mp_cmp(r, &key->q) != LTC_MP_LT || mp_cmp(s, &key->q) != LTC_MP_LT) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* w = 1/s mod q */ + if ((err = mp_invmod(s, &key->q, &w)) != CRYPT_OK) { goto error; } + + /* u1 = m * w mod q */ + if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != CRYPT_OK) { goto error; } + + /* u2 = r*w mod q */ + if ((err = mp_mulmod(r, &w, &key->q, &u2)) != CRYPT_OK) { goto error; } + + /* v = g^u1 * y^u2 mod p mod q */ + if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != CRYPT_OK) { goto error; } + if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(&v, &key->q, &v)) != CRYPT_OK) { goto error; } + + /* if r = v then we're set */ + if (mp_cmp(r, &v) == LTC_MP_EQ) { + *stat = 1; + } + + err = CRYPT_OK; +error: + mp_clear_multi(&w, &v, &u1, &u2, NULL); + return err; +} + +/** + Verify a DSA signature + @param sig The signature + @param siglen The length of the signature (octets) + @param hash The hash that was signed + @param hashlen The length of the hash that was signed + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param key The corresponding public DH key + @return CRYPT_OK if successful (even if the signature is invalid) +*/ +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key) +{ + int err; + mp_int r, s; + + if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* decode the sequence */ + if ((err = der_decode_sequence_multi(sig, siglen, + LTC_ASN1_INTEGER, 1UL, &r, + LTC_ASN1_INTEGER, 1UL, &s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* do the op */ + err = dsa_verify_hash_raw(&r, &s, hash, hashlen, stat, key); + +LBL_ERR: + mp_clear_multi(&r, &s, NULL); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_hash.c,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_key.c b/crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_key.c new file mode 100644 index 00000000000..71635d25912 --- /dev/null +++ b/crypto/userspace/libtomcrypt/pk/dsa/dsa_verify_key.c @@ -0,0 +1,100 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_verify_key.c + DSA implementation, verify a key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Verify a DSA key for validity + @param key The key to verify + @param stat [out] Result of test, 1==valid, 0==invalid + @return CRYPT_OK if successful +*/ +int dsa_verify_key(dsa_key *key, int *stat) +{ + mp_int tmp, tmp2; + int res, err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to an invalid key */ + *stat = 0; + + /* first make sure key->q and key->p are prime */ + if ((err = mp_prime_is_prime(&key->q, 8, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + if ((err = mp_prime_is_prime(&key->p, 8, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + /* now make sure that g is not -1, 0 or 1 and <p */ + if (mp_cmp_d(&key->g, 0) == LTC_MP_EQ || mp_cmp_d(&key->g, 1) == LTC_MP_EQ) { + return CRYPT_OK; + } + if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; } + if ((err = mp_sub_d(&key->p, 1, &tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp(&tmp, &key->g) == LTC_MP_EQ || mp_cmp(&key->g, &key->p) != LTC_MP_LT) { + err = CRYPT_OK; + goto error; + } + + /* 1 < y < p-1 */ + if (!(mp_cmp_d(&key->y, 1) == LTC_MP_GT && mp_cmp(&key->y, &tmp) == LTC_MP_LT)) { + err = CRYPT_OK; + goto error; + } + + /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */ + if ((err = mp_div(&tmp, &key->q, &tmp, &tmp2)) != CRYPT_OK) { goto error; } + if (mp_iszero(&tmp2) != LTC_MP_YES) { + err = CRYPT_OK; + goto error; + } + + if ((err = mp_exptmod(&key->g, &key->q, &key->p, &tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp_d(&tmp, 1) != LTC_MP_EQ) { + err = CRYPT_OK; + goto error; + } + + /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */ + if ((err = mp_exptmod(&key->y, &key->q, &key->p, &tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp_d(&tmp, 1) != LTC_MP_EQ) { + err = CRYPT_OK; + goto error; + } + + /* at this point we are out of tests ;-( */ + err = CRYPT_OK; + *stat = 1; +error: + mp_clear_multi(&tmp, &tmp2, NULL); + return err; +} +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_key.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ |