*/
-/* Generates DSA key pair. For now this uses group size of 160 bits. */
+/* Generates DSA key pair. The q length and hash comes as argument. */
-SILC_PKCS_ALG_GENERATE_KEY(silc_dsa_generate_key)
+static SilcBool
+silc_dsa_generate_key_int(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcUInt32 q_len, const char *hash,
+ SilcUInt32 keylen, SilcRng rng,
+ void **ret_public_key, void **ret_private_key)
{
DsaPublicKey *pubkey;
DsaPrivateKey *privkey;
SilcMPInt tmp, tmp2;
unsigned char rnd[4096];
- int i, len = (keylen + 7) / 8, q_len = 160 / 8;
+ int i, len = (keylen + 7) / 8;
+
+ q_len /= 8;
if (keylen < 768 || keylen > 16384)
return FALSE;
+ if (!silc_hash_is_supported(hash))
+ return FALSE;
+
pubkey = silc_calloc(1, sizeof(*pubkey));
if (!pubkey)
return FALSE;
return FALSE;
}
+ silc_hash_alloc(hash, &pubkey->hash);
+ silc_hash_alloc(hash, &privkey->hash);
+
silc_mp_init(&tmp);
silc_mp_init(&tmp2);
silc_mp_init(&privkey->p);
silc_mp_add(&tmp, &privkey->q, &privkey->q);
do {
- /* Create p. Take random data, this returns non-zero bytes. Make the
- number even. */
+ /* Create p. Take random data, this returns non-zero bytes. */
silc_rng_get_rn_data(rng, len - q_len, rnd, sizeof(rnd));
rnd[(len - q_len) - 1] &= ~1;
silc_mp_bin2mp(rnd, len - q_len, &tmp2);
return TRUE;
}
+/* Generates DSA key pair. Complies with FIPS186-2. Uses 160 bit q. */
+
+SILC_PKCS_ALG_GENERATE_KEY(silc_dsa_fips186_2_generate_key)
+{
+ return silc_dsa_generate_key_int(pkcs, 160, "sha1", keylen, rng,
+ ret_public_key, ret_private_key);
+}
+
+/* Generates DSA key pair. Complies with FIPS186-3. Same as the FIPS186-2
+ but determines the length of q automatically. */
+
+SILC_PKCS_ALG_GENERATE_KEY(silc_dsa_generate_key)
+{
+ SilcUInt32 q_len;
+ const char *hash;
+
+ if (keylen <= 1024) {
+ q_len = 160;
+ hash = "sha1";
+ } else if (keylen <= 2048) {
+ q_len = 224;
+ hash = "sha224";
+ } else {
+ q_len = 256;
+ hash = "sha256";
+ }
+
+ return silc_dsa_generate_key_int(pkcs, q_len, hash, keylen, rng,
+ ret_public_key, ret_private_key);
+}
+
/* Import DSA public key */
SILC_PKCS_ALG_IMPORT_PUBLIC_KEY(silc_dsa_import_public_key)
silc_mp_uninit(&key->q);
silc_mp_uninit(&key->g);
silc_mp_uninit(&key->y);
+ silc_hash_free(key->hash);
silc_free(key);
}
silc_mp_uninit(&key->g);
silc_mp_uninit(&key->y);
silc_mp_uninit(&key->x);
+ silc_hash_free(key->hash);
silc_free(key);
}
/* Compute hash if requested */
if (compute_hash) {
+ if (!hash)
+ hash = key->hash;
silc_hash_make(hash, src, src_len, hashr);
src = hashr;
src_len = silc_hash_len(hash);
+ if (src_len > key->group_order)
+ src_len = key->group_order;
}
stack = silc_stack_alloc(2048, silc_crypto_stack());
}
/* Hash data if requested */
- if (hash) {
+ if (compute_hash) {
+ if (!hash)
+ hash = key->hash;
silc_hash_make(hash, data, data_len, hashr);
data = hashr;
data_len = silc_hash_len(hash);
+ if (data_len > key->group_order)
+ data_len = key->group_order;
}
silc_mp_sinit(stack, &v);
/* Deliver result */
verify_cb(ret, context);
- if (hash)
+ if (compute_hash)
memset(hashr, 0, sizeof(hashr));
silc_mp_uninit(&v);
silc_mp_uninit(&w);
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2007 Pekka Riikonen
+ Copyright (C) 2007 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* DSA Public key */
typedef struct {
+ SilcHash hash; /* Default hash function */
SilcMPInt g; /* generator */
SilcMPInt p; /* prime */
SilcMPInt q; /* prime */
/* DSA Private key */
typedef struct {
+ SilcHash hash; /* Default hash function */
SilcMPInt g; /* generator */
SilcMPInt p; /* prime */
SilcMPInt q; /* prime */
SilcUInt16 group_order; /* group order (size) */
} DsaPrivateKey;
+SILC_PKCS_ALG_GENERATE_KEY(silc_dsa_fips186_2_generate_key);
SILC_PKCS_ALG_GENERATE_KEY(silc_dsa_generate_key);
SILC_PKCS_ALG_IMPORT_PUBLIC_KEY(silc_dsa_import_public_key);
SILC_PKCS_ALG_EXPORT_PUBLIC_KEY(silc_dsa_export_public_key);
everything else too about cryptography.
*/
-/* $Id$ */
/*
ChangeLog
if (!privkey)
return FALSE;
+ /* Default hash shall be sha1 */
+ silc_hash_alloc("sha1", &pubkey->hash);
+ silc_hash_alloc("sha1", &privkey->hash);
+
/* Initialize variables */
silc_mp_init(&privkey->n);
silc_mp_init(&privkey->e);
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* RSA Public Key */
typedef struct {
+ SilcHash hash; /* Default hash */
SilcMPInt n; /* modulus */
SilcMPInt e; /* public exponent */
int bits; /* bits in key */
/* RSA Private Key */
typedef struct {
+ SilcHash hash; /* Default hash */
SilcMPInt n; /* modulus */
SilcMPInt e; /* public exponent */
SilcMPInt d; /* private exponent */
silc_mp_uninit(&key->n);
silc_mp_uninit(&key->e);
+ silc_hash_free(key->hash);
silc_free(key);
}
silc_mp_uninit(&key->qP);
silc_mp_uninit(&key->p);
silc_mp_uninit(&key->q);
+ silc_hash_free(key->hash);
silc_free(key);
}
/* Compute hash */
if (compute_hash) {
+ if (!hash)
+ hash = key->hash;
silc_hash_make(hash, src, src_len, hashr);
src = hashr;
src_len = silc_hash_len(hash);
silc_buffer_set(&di, unpadded, len);
/* If hash isn't given, allocate the one given in digest info */
- if (!hash) {
- has_null = FALSE;
+ if (compute_hash) {
+ if (!hash) {
+ has_null = FALSE;
- /* Decode digest info */
- if (!silc_asn1_decode(asn1, &di,
- SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
- SILC_ASN1_SEQUENCE,
+ /* Decode digest info */
+ if (!silc_asn1_decode(asn1, &di,
+ SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
SILC_ASN1_SEQUENCE,
- SILC_ASN1_OID(&oid),
- SILC_ASN1_NULL_T(SILC_ASN1_OPTIONAL,
- SILC_ASN1_TAG_NULL, &has_null),
- SILC_ASN1_END,
- SILC_ASN1_END, SILC_ASN1_END))
- goto err;
-
- if (!silc_hash_alloc_by_oid(oid, &ihash)) {
- SILC_LOG_DEBUG(("Unknown OID %s", oid));
- goto err;
+ SILC_ASN1_SEQUENCE,
+ SILC_ASN1_OID(&oid),
+ SILC_ASN1_NULL_T(SILC_ASN1_OPTIONAL,
+ SILC_ASN1_TAG_NULL, &has_null),
+ SILC_ASN1_END,
+ SILC_ASN1_END, SILC_ASN1_END))
+ goto err;
+
+ if (!silc_hash_alloc_by_oid(oid, &ihash)) {
+ SILC_LOG_DEBUG(("Unknown OID %s", oid));
+ goto err;
+ }
+ hash = ihash;
}
- hash = ihash;
- }
- /* Hash the data */
- silc_hash_make(hash, data, data_len, hashr);
- data = hashr;
- data_len = silc_hash_len(hash);
- oid = (char *)silc_hash_get_oid(hash);
+ /* Hash the data */
+ silc_hash_make(hash, data, data_len, hashr);
+ data = hashr;
+ data_len = silc_hash_len(hash);
+ oid = (char *)silc_hash_get_oid(hash);
+ }
/* Encode digest info for comparison */
memset(&ldi, 0, sizeof(ldi));
silc_free(verify);
silc_mp_uninit(&mp_tmp2);
silc_mp_uninit(&mp_dst);
- if (hash)
+ if (compute_hash)
memset(hashr, 0, sizeof(hashr));
if (ihash)
silc_hash_free(ihash);
/* Compute hash if requested */
if (compute_hash) {
+ if (!hash)
+ hash = key->hash;
silc_hash_make(hash, src, src_len, hashr);
src = hashr;
src_len = silc_hash_len(hash);
}
/* Hash data if requested */
- if (hash) {
+ if (compute_hash) {
+ if (!hash)
+ hash = key->hash;
silc_hash_make(hash, data, data_len, hashr);
data = hashr;
data_len = silc_hash_len(hash);
memset(verify, 0, verify_len);
memset(unpadded, 0, sizeof(unpadded));
- if (hash)
+ if (compute_hash)
memset(hashr, 0, sizeof(hashr));
silc_free(verify);
silc_mp_uninit(&mp_tmp2);
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2003 - 2005 Pekka Riikonen
+ Copyright (C) 2003 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#ifndef SILCPKCS1_H
#define SILCPKCS1_H
-/****d* silccrypt/SilcPKCS1API/SilcPkcs1BlockType
+/****d* silccrypt/SilcPkcs1BlockType
*
* NAME
*
} SilcPkcs1BlockType;
/***/
-/****f* silccrypt/SilcPKCS1API/silc_pkcs1_encode
+/****f* silccrypt/silc_pkcs1_encode
*
* SYNOPSIS
*
SilcUInt32 dest_data_size,
SilcRng rng);
-/****f* silccrypt/SilcPKCS1API/silc_pkcs1_decode
+/****f* silccrypt/silc_pkcs1_decode
*
* SYNOPSIS
*
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
SilcUInt32 signature_len, \
unsigned char *data, \
SilcUInt32 data_len, \
+ SilcBool compute_hash, \
SilcHash hash, \
SilcRng rng, \
SilcPKCSVerifyCb verify_cb, \
SilcUInt32 signature_len, \
unsigned char *data, \
SilcUInt32 data_len, \
+ SilcBool compute_hash, \
SilcHash hash, \
SilcRng rng, \
SilcPKCSVerifyCb verify_cb, \
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#ifndef SILCRNG_H
#define SILCRNG_H
-/****s* silccrypt/SilcRNGAPI/SilcRng
+/****s* silccrypt/SilcRng
*
* NAME
*
/* Prototypes */
-/****f* silccrypt/SilcRNGAPI/silc_rng_alloc
+/****f* silccrypt/silc_rng_alloc
*
* SYNOPSIS
*
***/
SilcRng silc_rng_alloc(void);
-/****f* silccrypt/SilcRNGAPI/silc_rng_free
+/****f* silccrypt/silc_rng_free
*
* SYNOPSIS
*
***/
void silc_rng_free(SilcRng rng);
-/****f* silccrypt/SilcRNGAPI/silc_rng_init
+/****f* silccrypt/silc_rng_init
*
* SYNOPSIS
*
***/
void silc_rng_init(SilcRng rng);
-/****f* silccrypt/SilcRNGAPI/silc_rng_get_byte
+/****f* silccrypt/silc_rng_get_byte
*
* SYNOPSIS
*
***/
SilcUInt8 silc_rng_get_byte(SilcRng rng);
-/****f* silccrypt/SilcRNGAPI/silc_rng_get_byte_fast
+/****f* silccrypt/silc_rng_get_byte_fast
*
* SYNOPSIS
*
***/
SilcUInt8 silc_rng_get_byte_fast(SilcRng rng);
-/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn16
+/****f* silccrypt/silc_rng_get_rn16
*
* SYNOPSIS
*
***/
SilcUInt16 silc_rng_get_rn16(SilcRng rng);
-/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn32
+/****f* silccrypt/silc_rng_get_rn32
*
* SYNOPSIS
*
***/
SilcUInt32 silc_rng_get_rn32(SilcRng rng);
-/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn_string
+/****f* silccrypt/silc_rng_get_rn_string
*
* SYNOPSIS
*
***/
unsigned char *silc_rng_get_rn_string(SilcRng rng, SilcUInt32 len);
-/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn_data
+/****f* silccrypt/silc_rng_get_rn_data
*
* SYNOPSIS
*
SilcBool silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len,
unsigned char *buf, SilcUInt32 buf_size);
-/****f* silccrypt/SilcRNGAPI/silc_rng_add_noise
+/****f* silccrypt/silc_rng_add_noise
*
* SYNOPSIS
*
***/
void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, SilcUInt32 len);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_init
+/****f* silccrypt/silc_rng_global_init
*
* SYNOPSIS
*
***/
SilcBool silc_rng_global_init(SilcRng rng);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_uninit
+/****f* silccrypt/silc_rng_global_uninit
*
* SYNOPSIS
*
***/
SilcBool silc_rng_global_uninit(void);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_byte
+/****f* silccrypt/silc_rng_global_get_byte
*
* SYNOPSIS
*
***/
SilcUInt8 silc_rng_global_get_byte(void);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_byte_fast
+/****f* silccrypt/silc_rng_global_get_byte_fast
*
* SYNOPSIS
*
***/
SilcUInt8 silc_rng_global_get_byte_fast(void);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn16
+/****f* silccrypt/silc_rng_global_get_rn16
*
* SYNOPSIS
*
***/
SilcUInt16 silc_rng_global_get_rn16(void);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn32
+/****f* silccrypt/silc_rng_global_get_rn32
*
* SYNOPSIS
*
***/
SilcUInt32 silc_rng_global_get_rn32(void);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn_string
+/****f* silccrypt/silc_rng_global_get_rn_string
*
* SYNOPSIS
*
***/
unsigned char *silc_rng_global_get_rn_string(SilcUInt32 len);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn_data
+/****f* silccrypt/silc_rng_global_get_rn_data
*
* SYNOPSIS
*
SilcBool silc_rng_global_get_rn_data(SilcRng rng, SilcUInt32 len,
unsigned char *buf, SilcUInt32 buf_size);
-/****f* silccrypt/SilcRNGAPI/silc_rng_global_add_noise
+/****f* silccrypt/silc_rng_global_add_noise
*
* SYNOPSIS
*