+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.
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));
memset(key, 0, sizeof(key_len));
silc_free(key);
- silc_math_primegen_uninit();
silc_rng_free(rng);
silc_pkcs_free(pkcs);
if (server->pending_commands)
silc_dlist_uninit(server->pending_commands);
- silc_math_primegen_uninit(); /* XXX */
silc_free(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);
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;
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
[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]
silchash.c \
silchmac.c \
silcrng.c \
- silcpkcs.c
+ silcpkcs.c \
+ pkcs1.c
EXTRA_DIST = *.h
+/* $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,
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.
*/
/*
*/
#include "silcincludes.h"
+#include "rsa.h"
#define RSA_BLOCK_MIN_PAD_LEN 8
#define RSA_BLOCK_FIRST_OCTET 0x00
* 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;
* Blocks intended for public-key operation.
*/
case RSA_BlockPublic:
-
/*
* 0x00 || BT || Pad || 0x00 || ActualData
* 1 1 padLen 1 data_len
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;
}
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)
{
*/
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;
{
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 */
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) {
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) {
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;
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;
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,
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);
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);
#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
*
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"
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));
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));
silc_mp_bin2mp(key_data + 4 + e_len + 4, n_len, &key->n);
+ key->bits = n_len * 8;
+
return TRUE;
}
silc_mp_bin2mp(key_data + 4 + e_len + 4 + n_len + 4, d_len, &key->d);
+ key->bits = n_len * 8;
+
return TRUE;
}
/* 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--) {
/* 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--) {
/* 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--) {
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);
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,
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
#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.
/* 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;
/* 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");
/* 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;
/* 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;
/* 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;
/* 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;
/* 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];
/* 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;
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;
+}
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
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--) {
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. */
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
#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
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);
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;
/* 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);
-}
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;
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. */
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);
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));