view libtomcrypt/src/pk/dsa/dsa_encrypt_key.c @ 1499:2d450c1056e3

options: Complete the transition to numeric toggles (`#if') For the sake of review, this commit alters only the code; the affiliated comments within the source files also need to be updated, but doing so now would obscure the operational changes that have been made here. * All on/off options have been switched to the numeric `#if' variant; that is the only way to make this `default_options.h.in' thing work in a reasonable manner. * There is now some very minor compile-time checking of the user's choice of options. * NO_FAST_EXPTMOD doesn't seem to be used, so it has been removed. * ENABLE_USER_ALGO_LIST was supposed to be renamed DROPBEAR_USER_ALGO_LIST, and this commit completes that work. * DROPBEAR_FUZZ seems to be a relatively new, as-yet undocumented option, which was added by the following commit: commit 6e0b539e9ca0b5628c6c5a3d118ad6a2e79e8039 Author: Matt Johnston <[email protected]> Date: Tue May 23 22:29:21 2017 +0800 split out checkpubkey_line() separately It has now been added to `sysoptions.h' and defined as `0' by default. * The configuration option `DROPBEAR_PASSWORD_ENV' is no longer listed in `default_options.h.in'; it is no longer meant to be set by the user, and is instead left to be defined in `sysoptions.h' (where it was already being defined) as merely the name of the environment variable in question: DROPBEAR_PASSWORD To enable or disable use of that environment variable, the user must now toggle `DROPBEAR_USE_DROPBEAR_PASSWORD'. * The sFTP support is now toggled by setting `DROPBEAR_SFTPSERVER', and the path of the sFTP server program is set independently through the usual SFTPSERVER_PATH.
author Michael Witten <mfwitten@gmail.com>
date Thu, 20 Jul 2017 19:38:26 +0000
parents 6dba84798cd5
children
line wrap: on
line source

/* 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 dsa_encrypt_key.c
  DSA Crypto, Tom St Denis
*/

#ifdef LTC_MDSA

/**
  Encrypt a symmetric key with DSA
  @param in         The symmetric key you want to encrypt
  @param inlen      The length of the key to encrypt (octets)
  @param out        [out] The destination for the ciphertext
  @param outlen     [in/out] The max size and resulting size of the ciphertext
  @param prng       An active PRNG state
  @param wprng      The index of the PRNG you wish to use
  @param hash       The index of the hash you want to use
  @param key        The DSA key you want to encrypt to
  @return CRYPT_OK if successful
*/
int dsa_encrypt_key(const unsigned char *in,   unsigned long inlen,
                          unsigned char *out,  unsigned long *outlen,
                          prng_state *prng, int wprng, int hash,
                          dsa_key *key)
{
    unsigned char *expt, *skey;
    void          *g_pub, *g_priv;
    unsigned long  x, y;
    int            err;

    LTC_ARGCHK(in      != NULL);
    LTC_ARGCHK(out     != NULL);
    LTC_ARGCHK(outlen  != NULL);
    LTC_ARGCHK(key     != NULL);

    /* check that wprng/cipher/hash are not invalid */
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
       return err;
    }

    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
       return err;
    }

    if (inlen > hash_descriptor[hash].hashsize) {
       return CRYPT_INVALID_HASH;
    }

    /* make a random key and export the public copy */
    if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) {
       return err;
    }

    expt       = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
    skey       = XMALLOC(MAXBLOCKSIZE);
    if (expt == NULL  || skey == NULL) {
       if (expt != NULL) {
          XFREE(expt);
       }
       if (skey != NULL) {
          XFREE(skey);
       }
       mp_clear_multi(g_pub, g_priv, NULL);
       return CRYPT_MEM;
    }

    /* make a random g_priv, g_pub = g^x pair
       private key x should be in range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2)
     */
    if ((err = rand_bn_upto(g_priv, key->q, prng, wprng)) != CRYPT_OK) {
      goto LBL_ERR;
    }

    /* compute y */
    if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    /* make random key */
    x        = mp_unsigned_bin_size(key->p) + 1;
    if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    y = MAXBLOCKSIZE;
    if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    /* Encrypt key */
    for (x = 0; x < inlen; x++) {
      skey[x] ^= in[x];
    }

    err = der_encode_sequence_multi(out, outlen,
                                    LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID,
                                    LTC_ASN1_INTEGER,            1UL,                            g_pub,
                                    LTC_ASN1_OCTET_STRING,       inlen,                          skey,
                                    LTC_ASN1_EOL,                0UL,                            NULL);

LBL_ERR:
#ifdef LTC_CLEAN_STACK
    /* clean up */
    zeromem(expt,   mp_unsigned_bin_size(key->p) + 1);
    zeromem(skey,   MAXBLOCKSIZE);
#endif

    XFREE(skey);
    XFREE(expt);

    mp_clear_multi(g_pub, g_priv, NULL);
    return err;
}

#endif
/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */