diff dh_sys.c @ 143:5d99163f7e32 libtomcrypt-orig

import of libtomcrypt 0.99
author Matt Johnston <matt@ucc.asn.au>
date Sun, 19 Dec 2004 11:34:45 +0000
parents 7faae8f46238
children
line wrap: on
line diff
--- a/dh_sys.c	Tue Jun 15 14:07:21 2004 +0000
+++ b/dh_sys.c	Sun Dec 19 11:34:45 2004 +0000
@@ -13,7 +13,7 @@
                          prng_state *prng, int wprng, int hash,
                          dh_key *key)
 {
-    unsigned char pub_expt[768], dh_shared[768], skey[MAXBLOCKSIZE];
+    unsigned char *pub_expt, *dh_shared, *skey;
     dh_key pubkey;
     unsigned long x, y, z, hashsize, pubkeysize;
     int err;
@@ -36,36 +36,54 @@
         return CRYPT_INVALID_HASH;
     }
 
-    /* make a random key and export the public copy */
-    if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
-       return err;
+    /* allocate memory */
+    pub_expt  = XMALLOC(DH_BUF_SIZE);
+    dh_shared = XMALLOC(DH_BUF_SIZE);
+    skey      = XMALLOC(MAXBLOCKSIZE);
+    if (pub_expt == NULL || dh_shared == NULL || skey == NULL) {
+       if (pub_expt != NULL) {
+          XFREE(pub_expt);
+       }
+       if (dh_shared != NULL) {
+          XFREE(dh_shared);
+       }
+       if (skey != NULL) {
+          XFREE(skey);
+       }
+       return CRYPT_MEM;
     }
 
-    pubkeysize = sizeof(pub_expt);
+    /* make a random key and export the public copy */
+    if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
+       goto __ERR;
+    }
+
+    pubkeysize = DH_BUF_SIZE;
     if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
        dh_free(&pubkey);
-       return err;
+       goto __ERR;
     }
 
     /* now check if the out buffer is big enough */
     if (*len < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + keylen)) {
        dh_free(&pubkey);
-       return CRYPT_BUFFER_OVERFLOW;
+       err = CRYPT_BUFFER_OVERFLOW;
+       goto __ERR;
     }
 
     /* make random key */
     hashsize  = hash_descriptor[hash].hashsize;
 
-    x = (unsigned long)sizeof(dh_shared);
+    x = DH_BUF_SIZE;
     if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) {
        dh_free(&pubkey);
-       return err;
+       goto __ERR;
     }
     dh_free(&pubkey);
 
-    z = sizeof(skey);
+    z = MAXBLOCKSIZE;
     if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) {
-       return err;
+       goto __ERR;
     }
 
     /* store header */
@@ -93,21 +111,26 @@
     }
     *len = y;
 
+    err = CRYPT_OK;
+__ERR:
 #ifdef CLEAN_STACK
     /* clean up */
-    zeromem(pub_expt, sizeof(pub_expt));
-    zeromem(dh_shared, sizeof(dh_shared));
-    zeromem(skey, sizeof(skey));
+    zeromem(pub_expt,  DH_BUF_SIZE);
+    zeromem(dh_shared, DH_BUF_SIZE);
+    zeromem(skey,      MAXBLOCKSIZE);
 #endif
+    XFREE(skey);
+    XFREE(dh_shared);
+    XFREE(pub_expt);
 
-    return CRYPT_OK;
+    return err;
 }
 
 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
                          unsigned char *outkey, unsigned long *keylen, 
                          dh_key *key)
 {
-   unsigned char shared_secret[768], skey[MAXBLOCKSIZE];
+   unsigned char *shared_secret, *skey;
    unsigned long x, y, z,hashsize, keysize;
    int  hash, err;
    dh_key pubkey;
@@ -122,23 +145,38 @@
       return CRYPT_PK_NOT_PRIVATE;
    }
 
+   /* allocate ram */
+   shared_secret = XMALLOC(DH_BUF_SIZE);
+   skey          = XMALLOC(MAXBLOCKSIZE);
+   if (shared_secret == NULL || skey == NULL) {
+      if (shared_secret != NULL) {
+         XFREE(shared_secret);
+      }
+      if (skey != NULL) {
+         XFREE(skey);
+      }
+      return CRYPT_MEM;
+   }
+
    /* check if initial header should fit */
    if (inlen < PACKET_SIZE+1+4+4) {
-      return CRYPT_INVALID_PACKET;
+      err =  CRYPT_INVALID_PACKET;
+      goto __ERR;
    } else {
       inlen -= PACKET_SIZE+1+4+4;
    }
 
    /* is header correct? */
    if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK)  {
-      return err;
+      goto __ERR;
    }
 
    /* now lets get the hash name */
    y = PACKET_SIZE;
    hash = find_hash_id(in[y++]);
    if (hash == -1) {
-      return CRYPT_INVALID_HASH;
+      err = CRYPT_INVALID_HASH;
+      goto __ERR;
    }
 
    /* common values */
@@ -149,28 +187,29 @@
    
    /* now check if the imported key will fit */
    if (inlen < x) {
-      return CRYPT_INVALID_PACKET;
+      err = CRYPT_INVALID_PACKET;
+      goto __ERR;
    } else {
       inlen -= x;
    }
    
    y += 4;
    if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) {
-      return err;
+      goto __ERR;
    }
    y += x;
 
    /* make shared key */
-   x = (unsigned long)sizeof(shared_secret);
+   x = DH_BUF_SIZE;
    if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
       dh_free(&pubkey);
-      return err;
+      goto __ERR;
    }
    dh_free(&pubkey);
 
-   z = sizeof(skey);
+   z = MAXBLOCKSIZE;
    if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
-      return err;
+      goto __ERR;
    }
 
    /* load in the encrypted key */
@@ -178,14 +217,15 @@
    
    /* will the outkey fit as part of the input */
    if (inlen < keysize) {
-      return CRYPT_INVALID_PACKET;
+      err = CRYPT_INVALID_PACKET;
+      goto __ERR;
    } else {
       inlen -= keysize;
    }
    
    if (keysize > *keylen) {
        err = CRYPT_BUFFER_OVERFLOW;
-       goto done;
+       goto __ERR;
    }
    y += 4;
 
@@ -196,11 +236,15 @@
    }
 
    err = CRYPT_OK;
-done:
+__ERR:
 #ifdef CLEAN_STACK
-   zeromem(shared_secret, sizeof(shared_secret));
-   zeromem(skey, sizeof(skey));
+   zeromem(shared_secret, DH_BUF_SIZE);
+   zeromem(skey,          MAXBLOCKSIZE);
 #endif
+
+   XFREE(skey);
+   XFREE(shared_secret);
+
    return err;
 }
 
@@ -227,7 +271,7 @@
                        prng_state *prng, int wprng, dh_key *key)
 {
    mp_int a, b, k, m, g, p, p1, tmp;
-   unsigned char buf[520];
+   unsigned char *buf;
    unsigned long x, y;
    int err;
 
@@ -250,18 +294,23 @@
       return CRYPT_PK_INVALID_TYPE;
    }
 
+   /* allocate ram for buf */
+   buf = XMALLOC(520);
+
    /* make up a random value k,
     * since the order of the group is prime
     * we need not check if gcd(k, r) is 1 
     */
    if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) != 
        (unsigned long)(sets[key->idx].size)) {
-      return CRYPT_ERROR_READPRNG;
+      err = CRYPT_ERROR_READPRNG;
+      goto __ERR;
    }
 
    /* init bignums */
    if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != MP_OKAY) { 
-      return mpi_to_ltc_error(err);
+      err = mpi_to_ltc_error(err);
+      goto __ERR;
    }
 
    /* load k and m */
@@ -290,7 +339,7 @@
    /* check for overflow */
    if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(&a) + mp_unsigned_bin_size(&b)) > *outlen) {
       err = CRYPT_BUFFER_OVERFLOW;
-      goto done;
+      goto __ERR;
    }
    
    /* store header  */
@@ -310,7 +359,7 @@
    /* check if size too big */
    if (*outlen < y) {
       err = CRYPT_BUFFER_OVERFLOW;
-      goto done;
+      goto __ERR;
    }
 
    /* store header */
@@ -318,11 +367,14 @@
    *outlen = y;
 
    err = CRYPT_OK;
-   goto done;
+   goto __ERR;
 error:
    err = mpi_to_ltc_error(err);
-done:
+__ERR:
    mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);
+
+   XFREE(buf);
+
    return err;
 }