view libtomcrypt/src/pk/dsa/dsa_decrypt_key.c @ 1631:292f79307600

fix some gcc warnings (#73) * tweak string size fix gcc8 warnings ``` svr-agentfwd.c: In function 'bindagent': svr-agentfwd.c:254:53: warning: '%s' directive output may be truncated writing up to 107 bytes into a region of size between 0 and 107 [-Wformat-truncation=] snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile); ^~ ~~~~~~~~ svr-agentfwd.c:254:2: note: 'snprintf' output between 2 and 216 bytes into a destination of size 108 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` * cleanup signed/unsigned comparison fix gcc8 warnings ``` scp.c: In function 'do_local_cmd': scp.c:132:17: warning: comparison of integer expressions of different signedness: 'u_int' {aka 'unsigned int'} and 'int' [-Wsign-compare] for (i = 0; i < a->num; i++) ^ scpmisc.c: In function 'addargs': scpmisc.c:161:25: warning: comparison of integer expressions of different signedness: 'int' and 'u_int' {aka 'unsigned int'} [-Wsign-compare] } else if (args->num+2 >= nalloc) ^~ scpmisc.c: In function 'replacearg': scpmisc.c:183:12: warning: comparison of integer expressions of different signedness: 'u_int' {aka 'unsigned int'} and 'int' [-Wsign-compare] if (which >= args->num) ^~ scpmisc.c: In function 'freeargs': scpmisc.c:196:17: warning: comparison of integer expressions of different signedness: 'u_int' {aka 'unsigned int'} and 'int' [-Wsign-compare] for (i = 0; i < args->num; i++) ^ ``` see https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/misc.h.diff?r1=1.16&r2=1.17
author François Perrad <francois.perrad@gadz.org>
date Wed, 20 Mar 2019 15:25:15 +0100
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_decrypt_key.c
  DSA Crypto, Tom St Denis
*/

#ifdef LTC_MDSA

/**
  Decrypt an DSA encrypted key
  @param in       The ciphertext
  @param inlen    The length of the ciphertext (octets)
  @param out      [out] The plaintext
  @param outlen   [in/out] The max size and resulting size of the plaintext
  @param key      The corresponding private DSA key
  @return CRYPT_OK if successful
*/
int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen,
                          unsigned char *out, unsigned long *outlen,
                          dsa_key *key)
{
   unsigned char  *skey, *expt;
   void           *g_pub;
   unsigned long  x, y;
   unsigned long  hashOID[32] = { 0 };
   int            hash, err;
   ltc_asn1_list  decode[3];

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

   /* right key type? */
   if (key->type != PK_PRIVATE) {
      return CRYPT_PK_NOT_PRIVATE;
   }

   /* decode to find out hash */
   LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
   err = der_decode_sequence(in, inlen, decode, 1);
   if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
      return err;
   }

   hash = find_hash_oid(hashOID, decode[0].size);
   if (hash_is_valid(hash) != CRYPT_OK) {
      return CRYPT_INVALID_PACKET;
   }

   /* we now have the hash! */

   if ((err = mp_init(&g_pub)) != CRYPT_OK) {
      return err;
   }

   /* allocate memory */
   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(g_pub);
      return CRYPT_MEM;
   }

   LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER,          g_pub,      1UL);
   LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING,      skey,      MAXBLOCKSIZE);

   /* read the structure in now */
   if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
      goto LBL_ERR;
   }

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

   y = mp_unsigned_bin_size(key->p) + 1;
   y = MIN(y, MAXBLOCKSIZE);
   if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   /* ensure the hash of the shared secret is at least as big as the encrypt itself */
   if (decode[2].size > y) {
      err = CRYPT_INVALID_PACKET;
      goto LBL_ERR;
   }

   /* avoid buffer overflow */
   if (*outlen < decode[2].size) {
      *outlen = decode[2].size;
      err = CRYPT_BUFFER_OVERFLOW;
      goto LBL_ERR;
   }

   /* Decrypt the key */
   for (x = 0; x < decode[2].size; x++) {
     out[x] = expt[x] ^ skey[x];
   }
   *outlen = x;

   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(expt,   mp_unsigned_bin_size(key->p) + 1);
   zeromem(skey,   MAXBLOCKSIZE);
#endif

   XFREE(expt);
   XFREE(skey);

   mp_clear(g_pub);

   return err;
}

#endif

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