updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 20 Feb 2001 15:49:36 +0000 (15:49 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 20 Feb 2001 15:49:36 +0000 (15:49 +0000)
17 files changed:
CHANGES
apps/silc/clientutil.c
apps/silcd/server.c
apps/silcd/testi2.conf
lib/silccrypt/Makefile.am
lib/silccrypt/pkcs1.c
lib/silccrypt/pkcs1.h
lib/silccrypt/rsa.c
lib/silccrypt/silcpkcs.c
lib/silccrypt/silcpkcs.h
lib/silccrypt/silcrng.c
lib/silccrypt/silcrng.h
lib/silcmath/mpbin.c
lib/silcmath/mpbin.h
lib/silcmath/silcprimegen.c
lib/silcske/payload.c
lib/silcske/silcske.c

diff --git a/CHANGES b/CHANGES
index 9edaaa5a40870166b40b8491034f9d7ead1d67b4..faaa44cbd62a3b4621fbb976c018997d7fa0af51 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,19 @@
+Tue Feb 20 14:14:14 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * The RSA key length is now save to the RsaKey context in the
+         key generation process in lib/silccrypt/rsa.c.  The key length
+         is now used to figure out the maximum size of the block allowed
+         to be encrypted/signed.
+
+       * Added silc_mp_mp2bin_noalloc into lib/silcmath/mpbin.[ch].  It
+         is equivalent to the silc_mp_mp2bin but does not allocate any
+         memory.
+
+       * Changed silc_mp_mp2bin API to take length argument.  If it is
+         non-zero then the buffer is allocated that large.  If zero, then
+         the size is approximated using silc_mp_sizeinbase, which however
+         is not relieable.
+
 Mon Feb 19 19:59:28 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * The client entry's userinfo pointer must be always valid. 
index 210f50b02c5d2307f6a8bb4bf12a211bb97e6c38..22e84bdce37a2bee566488aff87d29d1962a2725 100644 (file)
@@ -435,7 +435,7 @@ New pair of keys will be created.  Please, answer to following questions.\n\
 
   rng = silc_rng_alloc();
   silc_rng_init(rng);
-  silc_math_primegen_init();
+  silc_rng_global_init(rng);
 
   if (!public_key) {
     memset(line, 0, sizeof(line));
@@ -490,7 +490,6 @@ New pair of keys will be created.  Please, answer to following questions.\n\
   memset(key, 0, sizeof(key_len));
   silc_free(key);
 
-  silc_math_primegen_uninit();
   silc_rng_free(rng);
   silc_pkcs_free(pkcs);
 
index 0d351bc00df39d9e430f6735042e9ee61870f23e..a41add7d9158fade694bdf2f45e16e1d058c7233 100644 (file)
@@ -96,7 +96,6 @@ void silc_server_free(SilcServer server)
     if (server->pending_commands)
       silc_dlist_uninit(server->pending_commands);
 
-    silc_math_primegen_uninit(); /* XXX */
     silc_free(server);
   }
 }
@@ -140,7 +139,7 @@ int silc_server_init(SilcServer server)
   /* Initialize random number generator for the server. */
   server->rng = silc_rng_alloc();
   silc_rng_init(server->rng);
-  silc_math_primegen_init(); /* XXX */
+  silc_rng_global_init(server->rng);
 
   /* Initialize hash functions for server to use */
   silc_hash_alloc("md5", &server->md5hash);
@@ -701,7 +700,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
     if (ctx->dest_id)
       silc_free(ctx->dest_id);
     silc_free(ctx);
-    sock->protocol = NULL;
+    if (sock)
+      sock->protocol = NULL;
     silc_server_disconnect_remote(server, sock, "Server closed connection: "
                                  "Key exchange failed");
     return;
index 35f54730a3ecf478eca431e08f08df91aa359faf..fe6247a1d0a8b9ff75a693d83810e3924412a3a0 100644 (file)
@@ -19,10 +19,10 @@ nobody:nobody
 Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
 
 [ServerInfo]
-lassi.kuo.fi.ssh.com:212.146.8.245:Kuopio, Finland:1334
+lassi.kuo.fi.ssh.com:10.2.1.7:Kuopio, Finland:1334
 
 [ListenPort]
-212.146.8.245:212.146.8.245:1334
+10.2.1.7:10.2.1.7:1334
 
 [Logging]
 infologfile:silcd2.log:10000
@@ -43,10 +43,10 @@ errorlogfile:silcd2.log:10000
 [AdminConnection]
 
 [ServerConnection]
-212.146.8.245:passwd:priikone:1333:1:1
+10.2.1.7:passwd:priikone:1333:1:1
 
 [RouterConnection]
-212.146.8.245:passwd:priikone:1335:1:1:0
+10.2.1.7:passwd:priikone:1335:1:1:0
 
 [DenyConnection]
 [RedirectClient]
index a1441d19e464be92c185adf7edf7308e1791190b..66a9fbe080e12843ae96b1ed3cf3c9fcf718c6a5 100644 (file)
@@ -35,7 +35,8 @@ libsilccrypt_a_SOURCES = \
        silchash.c \
        silchmac.c \
        silcrng.c \
-       silcpkcs.c
+       silcpkcs.c \
+       pkcs1.c
 
 EXTRA_DIST = *.h
 
index c3136f58eef0d4b39e9d625279dd07e429120a97..2ba6f3efbaf5a62ca753f28a4dc7a661a45d213b 100644 (file)
@@ -1,13 +1,15 @@
+/* $Id$ */
 /* 
    PKCS #1 RSA wrapper.
 
-   Heavily modified to work under SILC, code that is not needed in SILC has
-   been removed for good, and some code was fixed and changed.
+   Heavily modified to work under SILC, rewrote all interfaces, code that
+   is not needed in SILC has been removed for good, and some code was fixed
+   and changed.
 
    For example, RSA_DecodeOneBlock was not used at all by Mozilla, however,
-   I took this code in to use after doing some fixing.  Also, OAEP is removed
-   totally for now.  I'm not sure whether OAEP could be used in the future
-   with SILC but not for now.
+   I took this code in to use after doing some fixing (it had some bugs).  
+   Also, OAEP is removed totally for now.  I'm not sure whether OAEP could
+   be used in the future with SILC but not for now.
 
    This file also implements partial SILC PKCS API for RSA with PKCS #1.
    It is partial because all the other functions but encrypt, decrypt,
@@ -32,8 +34,8 @@
               and RFC 2437.
 
    Copyright notice: All code, including the SILC PKCS API code that is
-   not part of the Mozilla code, falls under the same license found attached
-   to this file, below.
+   not part of the Mozilla code, falls under the same license (MPL or GPL)
+   found attached to this file, below.
 */
 
 /*
@@ -75,6 +77,7 @@
  */
 
 #include "silcincludes.h"
+#include "rsa.h"
 
 #define RSA_BLOCK_MIN_PAD_LEN          8
 #define RSA_BLOCK_FIRST_OCTET          0x00
@@ -101,7 +104,7 @@ typedef enum {
  * the rules defined in PKCS #1.
  */
 static unsigned char *
-RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
+RSA_FormatOneBlock(unsigned int modulusLen, RSA_BlockType blockType,
                   unsigned char *data, unsigned int data_len)
 {
     unsigned char *block;
@@ -150,7 +153,6 @@ RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
        * Blocks intended for public-key operation.
        */
       case RSA_BlockPublic:
-
        /*
         * 0x00 || BT || Pad || 0x00 || ActualData
         *   1      1   padLen    1      data_len
@@ -161,17 +163,15 @@ RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
        for (i = 0; i < padLen; i++) {
            /* Pad with non-zero random data. */
            do {
-               RNG_GenerateGlobalRandomBytes(bp + i, 1);
+               silc_rng_global_get_byte(bp + i);
            } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
        }
        bp += padLen;
        *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
        memcpy(bp, data, data_len);
-
        break;
 
       default:
-       assert(0);
        silc_free(block);
        return NULL;
     }
@@ -181,7 +181,7 @@ RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
 
 static int
 RSA_FormatBlock(unsigned char **result, unsigned int *result_len,
-               unsigned modulusLen,
+               unsigned int modulusLen,
                RSA_BlockType blockType, unsigned char *data,
                unsigned int data_len)
 {
@@ -210,7 +210,7 @@ RSA_FormatBlock(unsigned char **result, unsigned int *result_len,
         */
        assert(data_len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
 
-       *result = RSA_FormatOneBlock(modulusLen, blockType, data);
+       *result = RSA_FormatOneBlock(modulusLen, blockType, data, data_len);
        if (result == NULL) {
            *result_len = 0;
            return FALSE;
@@ -244,17 +244,19 @@ RSA_DecodeOneBlock(unsigned char *data,
 {
     RSA_BlockType blockType;
     unsigned char *dp, *res;
-    unsigned int i, len;
+    unsigned int i, len = 0;
 
     dp = data;
-    if (*dp++ != RSA_BLOCK_FIRST_OCTET) {
+    if (dp[0] != RSA_BLOCK_FIRST_OCTET) {
        return NULL;
     }
 
-    blockType = (RSA_BlockType)*dp++;
+    blockType = (RSA_BlockType)dp[1];
     if (blockType != bt)
       return NULL;
 
+    dp += 2;
+
     switch (blockType) {
       case RSA_BlockPrivate0:
        /* Ignored */
@@ -267,10 +269,8 @@ RSA_DecodeOneBlock(unsigned char *data,
            if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
                break;
        }
-       if ((i == modulusLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
+       if (i == modulusLen)
            return NULL;
-       }
-       dp++;
        len = modulusLen - (dp - data);
        res = (unsigned char *) silc_malloc(len);
        if (res == NULL) {
@@ -284,10 +284,8 @@ RSA_DecodeOneBlock(unsigned char *data,
            if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
                break;
        }
-       if (i == modulusLen) {
+       if (i == modulusLen)
            return NULL;
-       }
-       dp++;
        len = modulusLen - (dp - data);
        res = (unsigned char *) silc_malloc(len);
        if (res == NULL) {
@@ -315,14 +313,13 @@ RSA_DecodeOneBlock(unsigned char *data,
 SILC_PKCS_API_ENCRYPT(pkcs1)
 {
   RsaKey *key = (RsaKey *)context;
-  int i, ret = TRUE;
   SilcInt mp_tmp;
   SilcInt mp_dst;
   unsigned char *padded;
-  unsigned int padded_len;
+  unsigned int padded_len, len = key->bits / 8;
 
   /* Pad data */
-  if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8,
+  if (!RSA_FormatBlock(&padded, &padded_len, len,
                       RSA_BlockPublic, src, src_len))
     return FALSE;
 
@@ -336,21 +333,20 @@ SILC_PKCS_API_ENCRYPT(pkcs1)
   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
   
   /* MP to data */
-  if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len))
-    ret = FALSE;
+  silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
+  *dst_len = len;
 
   memset(padded, 0, padded_len);
   silc_free(padded);
   silc_mp_clear(&mp_tmp);
   silc_mp_clear(&mp_dst);
 
-  return ret;
+  return TRUE;
 }
 
 SILC_PKCS_API_DECRYPT(pkcs1)
 {
   RsaKey *key = (RsaKey *)context;
-  int i, tmplen;
   SilcInt mp_tmp;
   SilcInt mp_dst;
   unsigned char *padded, *unpadded;
@@ -366,7 +362,7 @@ SILC_PKCS_API_DECRYPT(pkcs1)
   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
 
   /* MP to data */
-  padded = silc_mp_mp2bin(&mp_dst, &padded_len);
+  padded = silc_mp_mp2bin(&mp_dst, key->bits / 8, &padded_len);
 
   /* Unpad data */
   unpadded = RSA_DecodeOneBlock(padded, padded_len, 0, 
@@ -396,46 +392,46 @@ SILC_PKCS_API_DECRYPT(pkcs1)
 SILC_PKCS_API_SIGN(pkcs1)
 {
   RsaKey *key = (RsaKey *)context;
-  int i, ret = TRUE;
   SilcInt mp_tmp;
   SilcInt mp_dst;
   unsigned char *padded;
   unsigned int padded_len;
+  unsigned int len = key->bits / 8;
 
   /* Pad data */
-  if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8,
-                      RSA_BlockPrivate, src, src_len))
+  if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate, 
+                      src, src_len))
     return FALSE;
 
   silc_mp_init_set_ui(&mp_tmp, 0);
   silc_mp_init_set_ui(&mp_dst, 0);
 
   /* Data to MP */
-  silc_mp_bin2mp(padded, padded_len, &mp_tmp);
+  silc_mp_bin2mp(padded, len, &mp_tmp);
 
   /* Sign */
   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
   
   /* MP to data */
-  if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len))
-    ret = FALSE;
+  silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
+  *dst_len = len;
 
   memset(padded, 0, padded_len);
   silc_free(padded);
   silc_mp_clear(&mp_tmp);
   silc_mp_clear(&mp_dst);
 
-  return ret;
+  return TRUE;
 }
 
 SILC_PKCS_API_VERIFY(pkcs1)
 {
   RsaKey *key = (RsaKey *)context;
-  int i, ret = TRUE;
-  SilcInt mp_tmp, mp_tmp2;
+  int ret = TRUE;
+  SilcInt mp_tmp2;
   SilcInt mp_dst;
-  unsigned char *verify, unpadded;
-  unsigned int verify_len;
+  unsigned char *verify, *unpadded;
+  unsigned int verify_len, len = key->bits / 8;
 
   silc_mp_init_set_ui(&mp_tmp2, 0);
   silc_mp_init_set_ui(&mp_dst, 0);
@@ -447,10 +443,10 @@ SILC_PKCS_API_VERIFY(pkcs1)
   rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
 
   /* MP to data */
-  verify = silc_mp_mp2bin(&mp_dst, &verify_len);
+  verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
 
   /* Unpad data */
-  unpadded = RSA_DecodeOneBlock(verify, verify_len, 0, 
+  unpadded = RSA_DecodeOneBlock(verify, len, 0, 
                                RSA_BlockPrivate, &verify_len);
   if (!unpadded) {
     memset(verify, 0, verify_len);
index 7ed3e97d51b6ffe27fae12ca3a3150e9a113445c..38937aee59c3195c03bd8be8e35e2153922f0baf 100644 (file)
 #ifndef PKCS1_H
 #define PKCS1_H
 
-/* 
-   PKCS #1 RSA wrapper.
-
-   Heavily modified to work under SILC, code that is not needed in SILC has
-   been removed for good, and some code was fixed and changed.
-
-   For example, RSA_DecodeOneBlock was not used at all by Mozilla, however,
-   I took this code in to use after doing some fixing.  Also, OAEP is removed
-   totally for now.  I'm not sure whether OAEP could be used in the future
-   with SILC but not for now.
-
-   This file also implements partial SILC PKCS API for RSA with PKCS #1.
-   It is partial because all the other functions but encrypt, decrypt,
-   sign and verify are common.
-
-   Note:
-
-   The mandatory PKCS #1 implementation in SILC must be compliant to either
-   PKCS #1 version 1.5 or PKCS #1 version 2 with the following notes:
-   The signature encoding is always in same format as the encryption
-   encoding regardles of the PKCS #1 version.  The signature with
-   appendix (with hash algorithm OID in the data) must not be used
-   in the SILC.  Rationale for this is that there is no binding between
-   the PKCS #1 OIDs and the hash algorithms used in the SILC protocol.
-   Hence, the encoding is always in PKCS #1 version 1.5 format.
-
-   Any questions and comments regarding this modified version should be
-   sent to priikone@poseidon.pspt.fi.
-
-   References: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc,
-               ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1.asc,
-              and RFC 2437.
-*/
-
 /*
  * SILC PKCS API for PKCS #1
  *
index c65283e7422c28a9fd9bf32745b64f9ac4e4dbc4..4fd1dc1b38de527cff288ad6eeff0afbbf0272a8 100644 (file)
      try to find the smallest possible d by doing modinv(e, lcm(phi)) instead
      of modinv(e, phi).  Note: this is not security fix but optimization.
 
+   o Tue Feb 20 13:58:58 EET 2001  Pekka
+
+     Set key->bits in rsa_generate_key.  It is the modulus length in bits.
+     The `tmplen' in encrypt, decrypt, sign and verify PKCS API functions
+     is now calculated by (key->bits + 7) / 8.  It is the length of one block.
+
 */
 
 #include "silcincludes.h"
@@ -125,8 +131,8 @@ SILC_PKCS_API_GET_PUBLIC_KEY(rsa)
   unsigned int e_len, n_len;
   unsigned char tmp[4];
 
-  e = silc_mp_mp2bin(&key->e, &e_len);
-  n = silc_mp_mp2bin(&key->n, &n_len);
+  e = silc_mp_mp2bin(&key->e, 0, &e_len);
+  n = silc_mp_mp2bin(&key->n, key->bits / 8, &n_len);
 
   *ret_len = e_len + 4 + n_len + 4;
   ret = silc_calloc(*ret_len, sizeof(unsigned char));
@@ -164,9 +170,9 @@ SILC_PKCS_API_GET_PRIVATE_KEY(rsa)
   unsigned int e_len, n_len, d_len;
   unsigned char tmp[4];
 
-  e = silc_mp_mp2bin(&key->e, &e_len);
-  n = silc_mp_mp2bin(&key->n, &n_len);
-  d = silc_mp_mp2bin(&key->d, &d_len);
+  e = silc_mp_mp2bin(&key->e, 0, &e_len);
+  n = silc_mp_mp2bin(&key->n, key->bits / 8, &n_len);
+  d = silc_mp_mp2bin(&key->d, 0, &d_len);
 
   *ret_len = e_len + 4 + n_len + 4 + d_len + 4;
   ret = silc_calloc(*ret_len, sizeof(unsigned char));
@@ -233,6 +239,8 @@ SILC_PKCS_API_SET_PUBLIC_KEY(rsa)
 
   silc_mp_bin2mp(key_data + 4 + e_len + 4, n_len, &key->n);
 
+  key->bits = n_len * 8;
+
   return TRUE;
 }
 
@@ -280,6 +288,8 @@ SILC_PKCS_API_SET_PRIVATE_KEY(rsa)
 
   silc_mp_bin2mp(key_data + 4 + e_len + 4 + n_len + 4, d_len, &key->d);
 
+  key->bits = n_len * 8;
+
   return TRUE;
 }
 
@@ -341,7 +351,7 @@ SILC_PKCS_API_ENCRYPT(rsa)
   /* Encrypt */
   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
   
-  tmplen = (1024 + 7) / 8;
+  tmplen = (key->bits + 7) / 8;
 
   /* Format the MP int back into data */
   for (i = tmplen; i > 0; i--) {
@@ -375,7 +385,7 @@ SILC_PKCS_API_DECRYPT(rsa)
   /* Decrypt */
   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
 
-  tmplen = (1024 + 7) / 8;
+  tmplen = (key->bits + 7) / 8;
 
   /* Format the MP int back into data */
   for (i = tmplen; i > 0; i--) {
@@ -409,7 +419,7 @@ SILC_PKCS_API_SIGN(rsa)
   /* Sign */
   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
 
-  tmplen = (1024 + 7) / 8;
+  tmplen = (key->bits + 7) / 8;
 
   /* Format the MP int back into data */
   for (i = tmplen; i > 0; i--) {
@@ -487,6 +497,9 @@ void rsa_generate_keys(RsaKey *key, unsigned int bits,
   silc_mp_init(&pm1);
   silc_mp_init(&qm1);
 
+  /* Set modulus length */
+  key->bits = bits;
+
   /* Set the primes */
   silc_mp_set(&key->p, p);
   silc_mp_set(&key->q, q);
index 74870ec8a33f0c4ee4361190d4e521efa99841dc..c193fc87c2d96116c86daf678db6f1fe305e9eb7 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 1997 - 2000 Pekka Riikonen
+  Copyright (C) 1997 - 2001 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
 #include "silcincludes.h"
 
 #include "rsa.h"
+#include "pkcs1.h"
 
 /* List of all PKCS's in SILC. PKCS's don't support SIM's thus
    only static declarations are possible. XXX: I hope this to change
    real soon. */
 SilcPKCSObject silc_pkcs_list[] =
 {
+  /* RSA with PKCS #1 (Uses directly routines from Raw RSA operations) */
+  /*
+  { "rsa", &silc_rsa_data_context, 
+    silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
+    silc_rsa_get_private_key, silc_rsa_set_public_key,
+    silc_rsa_set_private_key, silc_rsa_context_len,
+    silc_rsa_data_context_len, silc_rsa_set_arg,
+    silc_pkcs1_encrypt, silc_pkcs1_decrypt,
+    silc_pkcs1_sign, silc_pkcs1_verify },
+  */
+
+  /* Raw RSA operations */
   { "rsa", &silc_rsa_data_context, 
     silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
     silc_rsa_get_private_key, silc_rsa_set_public_key,
index 8183b3ac561f161c30cca7477f1a2f0bd988d08b..c726cfa80c2e81c45a9ed2d78153458710fb8c97 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 1997 - 2000 Pekka Riikonen
+  Copyright (C) 1997 - 2001 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
index 9da70dd93f9449a03398dfba3fbf2f3147b8ced0..742cb59a9da559cb0ae053e780e1a930c7771c73 100644 (file)
 #undef SILC_RNG_DEBUG
 /* #define SILC_RNG_DEBUG */
 
+static unsigned int silc_rng_get_position(SilcRng rng);
+static void silc_rng_stir_pool(SilcRng rng);
+static void silc_rng_xor(SilcRng rng, unsigned int val, unsigned int pos);
+static void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, 
+                              unsigned int len);
+static void silc_rng_exec_command(SilcRng rng, char *command);
+static void silc_rng_get_hard_noise(SilcRng rng);
+static void silc_rng_get_medium_noise(SilcRng rng);
+static void silc_rng_get_soft_noise(SilcRng rng);
+
 /* 
    SILC SilcRng State context.
 
@@ -167,7 +177,7 @@ void silc_rng_init(SilcRng rng)
 
 /* This function gets 'soft' noise from environment. */
 
-void silc_rng_get_soft_noise(SilcRng rng)
+static void silc_rng_get_soft_noise(SilcRng rng)
 {
   struct tms ptime;
   
@@ -203,7 +213,7 @@ void silc_rng_get_soft_noise(SilcRng rng)
 
 /* This function gets noise from different commands */
 
-void silc_rng_get_medium_noise(SilcRng rng)
+static void silc_rng_get_medium_noise(SilcRng rng)
 {
   silc_rng_exec_command(rng, "ps -lefaww 2> /dev/null");
   silc_rng_exec_command(rng, "ls -afiln 2> /dev/null");
@@ -218,7 +228,7 @@ void silc_rng_get_medium_noise(SilcRng rng)
 /* This function gets 'hard' noise from environment. This tries to
    get the noise from /dev/random if available. */
 
-void silc_rng_get_hard_noise(SilcRng rng)
+static void silc_rng_get_hard_noise(SilcRng rng)
 {
   char buf[32];
   int fd, len, i;
@@ -244,7 +254,7 @@ void silc_rng_get_hard_noise(SilcRng rng)
 
 /* Execs command and gets noise from its output */
 
-void silc_rng_exec_command(SilcRng rng, char *command)
+static void silc_rng_exec_command(SilcRng rng, char *command)
 {
   char buf[2048];
   FILE *fd;
@@ -277,8 +287,8 @@ void silc_rng_exec_command(SilcRng rng, char *command)
 /* This function adds the contents of the buffer as noise into random 
    pool. After adding the noise the pool is stirred. */
 
-void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, 
-                       unsigned int len)
+static void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, 
+                              unsigned int len)
 {
   unsigned int i, pos;
 
@@ -297,7 +307,7 @@ void silc_rng_add_noise(SilcRng rng, unsigned char *buffer,
 
 /* XOR's data into the pool */
 
-void silc_rng_xor(SilcRng rng, unsigned int val, unsigned int pos)
+static void silc_rng_xor(SilcRng rng, unsigned int val, unsigned int pos)
 {
   assert(rng != NULL);
   rng->pool[pos] ^= val + val;
@@ -306,7 +316,7 @@ void silc_rng_xor(SilcRng rng, unsigned int val, unsigned int pos)
 /* This function stirs the random pool by encrypting buffer in CFB 
    (cipher feedback) mode with SHA1 algorithm. */
 
-void silc_rng_stir_pool(SilcRng rng)
+static void silc_rng_stir_pool(SilcRng rng)
 {
   int i;
   unsigned long iv[5];
@@ -343,7 +353,7 @@ void silc_rng_stir_pool(SilcRng rng)
 /* Returns next position where data is fetched from the pool or
    put to the pool. */
 
-unsigned int silc_rng_get_position(SilcRng rng)
+static unsigned int silc_rng_get_position(SilcRng rng)
 {
   SilcRngState next;
   unsigned int pos;
@@ -430,3 +440,62 @@ unsigned char *silc_rng_get_rn_data(SilcRng rng, unsigned int len)
 
   return data;
 }
+
+/* Global RNG. This is global RNG that application can initialize so
+   that any part of code anywhere can use RNG without having to allocate
+   new RNG object everytime.  If this is not initialized then these routines
+   will fail.  Note: currently in SILC applications always initialize this. */
+
+SilcRng global_rng = NULL;
+
+/* Initialize global RNG. If `rng' is provided it is set as the global
+   RNG object (it can be allocated by the application for example). */
+
+int silc_rng_global_init(SilcRng rng)
+{
+  if (rng)
+    global_rng = rng;
+  else
+    global_rng = silc_rng_alloc();
+
+  return TRUE;
+}
+
+/* Uninitialize global RNG */
+
+int silc_rng_global_uninit()
+{
+  if (global_rng) {
+    silc_rng_free(global_rng);
+    global_rng = NULL;
+  }
+
+  return TRUE;
+}
+
+/* These are analogous to the functions above. */
+
+unsigned char silc_rng_global_get_byte()
+{
+  return global_rng ? silc_rng_get_byte(global_rng) : 0;
+}
+
+unsigned short silc_rng_global_get_rn16()
+{
+  return global_rng ? silc_rng_get_rn16(global_rng) : 0;
+}
+
+unsigned int silc_rng_global_get_rn32()
+{
+  return global_rng ? silc_rng_get_rn32(global_rng) : 0;
+}
+
+unsigned char *silc_rng_global_get_rn_string(unsigned int len)
+{
+  return global_rng ? silc_rng_get_rn_string(global_rng, len) : NULL;
+}
+
+unsigned char *silc_rng_global_get_rn_data(unsigned int len)
+{
+  return global_rng ? silc_rng_get_rn_data(global_rng, len) : NULL;
+}
index 7dfc2d78982823b293eaa30589509bc8c5f45844..40084bc111360e5cf84d4d09d891026982c9e2fb 100644 (file)
@@ -34,19 +34,18 @@ typedef struct SilcRngObjectStruct *SilcRng;
 SilcRng silc_rng_alloc();
 void silc_rng_free(SilcRng rng);
 void silc_rng_init(SilcRng rng);
-void silc_rng_get_soft_noise(SilcRng rng);
-void silc_rng_get_medium_noise(SilcRng rng);
-void silc_rng_get_hard_noise(SilcRng rng);
-void silc_rng_exec_command(SilcRng rng, char *command);
-void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, 
-                       unsigned int len);
-void silc_rng_xor(SilcRng rng, unsigned int val, unsigned int pos);
-void silc_rng_stir_pool(SilcRng rng);
-unsigned int silc_rng_get_position(SilcRng rng);
 unsigned char silc_rng_get_byte(SilcRng rng);
 unsigned short silc_rng_get_rn16(SilcRng rng);
 unsigned int silc_rng_get_rn32(SilcRng rng);
 unsigned char *silc_rng_get_rn_string(SilcRng rng, unsigned int len);
 unsigned char *silc_rng_get_rn_data(SilcRng rng, unsigned int len);
 
+int silc_rng_global_init(SilcRng rng);
+int silc_rng_global_uninit();
+unsigned char silc_rng_global_get_byte();
+unsigned short silc_rng_global_get_rn16();
+unsigned int silc_rng_global_get_rn32();
+unsigned char *silc_rng_global_get_rn_string(unsigned int len);
+unsigned char *silc_rng_global_get_rn_data(unsigned int len);
+
 #endif
index 6e0e6eadb384663e068cf60c28445d6f26c2d86e..8b598aa1a1f4759196ee96291b3510cd95dcba27 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 2000 Pekka Riikonen
+  Copyright (C) 2000 - 2001 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
 #include "silcincludes.h"
 
 /* Encodes MP integer into binary data. Returns allocated data that
-   must be free'd by the caller. */
+   must be free'd by the caller. If `len' is provided the destination
+   buffer is allocated that large. If zero then the size is approximated. */
 
-unsigned char *silc_mp_mp2bin(SilcInt *val, unsigned int *ret_len)
+unsigned char *silc_mp_mp2bin(SilcInt *val, unsigned int len,
+                             unsigned int *ret_len)
 {
   int i;
   unsigned int size;
   unsigned char *ret;
   SilcInt tmp;
 
-  size = (silc_mp_sizeinbase(val, 2) + 7) / 8;
+  size = (len ? len : ((silc_mp_sizeinbase(val, 2) + 7) / 8));
   ret = silc_calloc(size, sizeof(*ret));
-
+  
   silc_mp_init_set(&tmp, val);
 
   for (i = size; i > 0; i--) {
@@ -49,6 +51,27 @@ unsigned char *silc_mp_mp2bin(SilcInt *val, unsigned int *ret_len)
   return ret;
 }
 
+/* Samve as above but does not allocate any memory.  The encoded data is
+   returned into `dst' and it's length to the `ret_len'. If `dst_len is
+   non-zero then the destination buffer is assumbed to be that large. */
+
+void silc_mp_mp2bin_noalloc(SilcInt *val, unsigned char *dst,
+                           unsigned int dst_len)
+{
+  int i;
+  unsigned int size = dst_len;
+  SilcInt tmp;
+
+  silc_mp_init_set(&tmp, val);
+
+  for (i = size; i > 0; i--) {
+    dst[i - 1] = (unsigned char)(silc_mp_get_ui(&tmp) & 0xff);
+    silc_mp_fdiv_q_2exp(&tmp, &tmp, 8);
+  }
+
+  silc_mp_clear(&tmp);
+}
+
 /* Decodes binary data into MP integer. The integer sent as argument
    must be initialized. */
 
index 41ebf12b711ff1365a991b60f0b605621ccf1252..f32f19a33726c3da8901c01a8859780f8a3d5a3d 100644 (file)
@@ -4,7 +4,7 @@
   
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 2000 Pekka Riikonen
+  Copyright (C) 2000 - 2001 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 MPBIN_H
 #define MPBIN_H
 
-unsigned char *silc_mp_mp2bin(SilcInt *val, unsigned int *ret_len);
+unsigned char *silc_mp_mp2bin(SilcInt *val, unsigned int len,
+                             unsigned int *ret_len);
+void silc_mp_mp2bin_noalloc(SilcInt *val, unsigned char *dst,
+                           unsigned int dst_len);
 void silc_mp_bin2mp(unsigned char *data, unsigned int len, SilcInt *ret);
 
 #endif
index b86a6aadf7ccd3f21bd1eb85811abb3ab1d580e1..decb9538edbe46c2ea00675b5377f98359a2bdde 100644 (file)
 
 #include "silcincludes.h"
 
-/* XXX This must be temporary solution!! yucky! */
-/* Global random pool used for all prime generation. All primes generated
-   in SILC uses this same pool. Before primes can be generated one must
-   call silc_math_primegen_init. */
-static SilcRng primegen_rng;
-
 /* 
    Fixed primetable for small prime division. We use this primetable to 
    test if possible prime is divisible any of these. Primetable is NULL 
@@ -208,9 +202,6 @@ int silc_math_gen_prime(SilcInt *prime, unsigned int bits, int verbose)
   unsigned int *spmods;
   SilcInt r, base, tmp, tmp2, oprime;
 
-  /* XXX */
-  assert(primegen_rng != NULL);
-
   silc_mp_init(&r);
   silc_mp_init_set_ui(&base, 2);
   silc_mp_init(&tmp);
@@ -220,7 +211,7 @@ int silc_math_gen_prime(SilcInt *prime, unsigned int bits, int verbose)
   SILC_LOG_DEBUG(("Generating new prime"));
 
   /* Get random number */
-  numbuf = silc_rng_get_rn_string(primegen_rng, (bits / 8));
+  numbuf = silc_rng_global_get_rn_string((bits / 8));
   if (!numbuf)
     return FALSE;
 
@@ -348,24 +339,3 @@ int silc_math_prime_test(SilcInt *p)
   /* Number is probably a prime */
   return TRUE;
 }
-
-/* XXX This must temporary solution!! */
-/* Initializes the random pool used to generated primes */
-
-void silc_math_primegen_init()
-{
-  SILC_LOG_DEBUG(("Start"));
-
-  if (primegen_rng == NULL) {
-    primegen_rng = silc_rng_alloc();
-    silc_rng_init(primegen_rng);
-  }
-}
-
-/* XXX This must temporary solution!! */
-/* Uninitializes random pool */
-
-void silc_math_primegen_uninit()
-{
-  silc_rng_free(primegen_rng);
-}
index c491f29e2f5e6562f7746c463724a96b502cf528..d0526135f27d38fec05c735fa5b1c8a6eefbb0b0 100644 (file)
@@ -282,7 +282,7 @@ SilcSKEStatus silc_ske_payload_one_encode(SilcSKE ske,
     return SILC_SKE_STATUS_ERROR;
 
   /* Encode the integer into binary data */
-  e_str = silc_mp_mp2bin(&payload->e, &e_len);
+  e_str = silc_mp_mp2bin(&payload->e, 0, &e_len);
   if (!e_str)
     return SILC_SKE_STATUS_ERROR;
 
@@ -421,7 +421,7 @@ SilcSKEStatus silc_ske_payload_two_encode(SilcSKE ske,
     return SILC_SKE_STATUS_ERROR;
 
   /* Encode the integer into HEX string */
-  f_str = silc_mp_mp2bin(&payload->f, &f_len);
+  f_str = silc_mp_mp2bin(&payload->f, 0, &f_len);
 
   /* Allocate channel payload buffer. The length of the buffer
      is 2 + 2 + public key + 2 + f + 2 + signature. */
index bc84849fdea90740a5597a0b0029f48380c07492..c8de900eefde4bc01d11c6a52311fe200e14371a 100644 (file)
@@ -1161,9 +1161,9 @@ SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
 
   SILC_LOG_DEBUG(("Start"));
 
-  e = silc_mp_mp2bin(&ske->ke1_payload->e, &e_len);
-  f = silc_mp_mp2bin(&ske->ke2_payload->f, &f_len);
-  KEY = silc_mp_mp2bin(ske->KEY, &KEY_len);
+  e = silc_mp_mp2bin(&ske->ke1_payload->e, 0, &e_len);
+  f = silc_mp_mp2bin(&ske->ke2_payload->f, 0, &f_len);
+  KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
 
   buf = silc_buffer_alloc(ske->start_payload_copy->len + 
                          ske->pk_len + e_len + f_len + KEY_len);
@@ -1226,7 +1226,7 @@ SilcSKEStatus silc_ske_process_key_material(SilcSKE ske,
   SILC_LOG_DEBUG(("Start"));
 
   /* Encode KEY to binary data */
-  tmpbuf = silc_mp_mp2bin(ske->KEY, &klen);
+  tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
 
   buf = silc_buffer_alloc(1 + klen + hash_len);
   silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));