diff options
Diffstat (limited to 'core/lib/libtomcrypt/src/pk/dh')
-rw-r--r-- | core/lib/libtomcrypt/src/pk/dh/dh.c | 217 | ||||
-rw-r--r-- | core/lib/libtomcrypt/src/pk/dh/sub.mk | 2 |
2 files changed, 219 insertions, 0 deletions
diff --git a/core/lib/libtomcrypt/src/pk/dh/dh.c b/core/lib/libtomcrypt/src/pk/dh/dh.c new file mode 100644 index 0000000..d97f704 --- /dev/null +++ b/core/lib/libtomcrypt/src/pk/dh/dh.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2001-2007, Tom St Denis + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <tomcrypt.h> + +#ifdef LTC_LINARO_FIX_DH + +#include <stdint.h> +/* + * Make a DH key [private key pair] + * @param prng An active PRNG state + * @param wprng The index for the PRNG you desire to use + * @param keysize The key size (octets) desired of the private key + * @param q If not null, then the private key is in the range + * [2, q-2] where q is called the subprime + * @param xbits If not 0, then the private key has 'xbits' bits + * @note The private key must always be less than p-1 + * @param key [in/out] Where the newly created DH key will be stored + * g and p are provided as input in the key + * type, x and y are output of this function + * @return CRYPT_OK if successful, note: on error all allocated memory will be + * freed automatically. +*/ + +int dh_make_key(prng_state *prng, int wprng, void *q, int xbits, dh_key *key) +{ + const int limit = 500; /* number of tries */ + int err, i; + int key_size = 0; /* max key size, in bytes */ + int key_size_p = 0; /* key size of p */ + int key_size_q = 0; /* key size of p */ + void *arg_mod; + uint8_t *buf = 0; /* intermediate buffer to have a raw random */ + int found = 0; + + /* + * Check the arguments + */ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key->g != NULL); + LTC_ARGCHK(key->p != NULL); + err = prng_is_valid(wprng); + if (err != CRYPT_OK) + return err; + + /* + * Set the key size and check constraints + */ + if (xbits) { + LTC_ARGCHK((xbits % 8) == 0); + key_size = xbits / 8; + } + key_size_p = mp_unsigned_bin_size(key->p); + if (q) + key_size_q = mp_unsigned_bin_size(q); + if (key_size) { + /* check the constraints */ + LTC_ARGCHK(key_size <= key_size_p); + LTC_ARGCHK((q == NULL) || (key_size <= key_size_q)); + } else { + if (q) + key_size = MIN(key_size_p, key_size_q); + else + key_size =key_size_p; + } + + /* Set the argument we will make the modulo against to */ + if ((q != NULL) && (key_size_q < key_size_p)) + arg_mod = q; + else + arg_mod = key->p; + + /* initialize the key */ + key->x = NULL; + key->y = NULL; + err = mp_init_multi(&key->x, &key->y, NULL); + if (err != CRYPT_OK) + goto error; + + /* Initialize the buffer used to store the random number */ + buf = XMALLOC(key_size); + if (buf == NULL) { + err = CRYPT_MEM; + goto error; + } + + for (i = 0; (i < limit) && (!found); i++) { + /* generate the private key in a raw-buffer */ + if (prng_descriptor[wprng]->read(buf, key_size, prng) != + (unsigned long)key_size) { + err = CRYPT_ERROR_READPRNG; + goto error; + } + + /* make sure it is on the right number of bits */ + if (xbits) + buf[0] |= 0x80; + + /* transform it as a Big Number */ + err = mp_read_unsigned_bin(key->x, buf, key_size); + if (err != CRYPT_OK) + goto error; + + /* + * Transform it as a Big Number compatible with p and q + */ + err = mp_read_unsigned_bin(key->y, buf, key_size); + if (err != CRYPT_OK) + goto error; + err = mp_mod(key->y, arg_mod, key->x); + if (err != CRYPT_OK) + goto error; + + /* + * Check the constraints + * - x < p is ok by construction + * - x < q-1: + * - x contains xbits + */ + if (xbits) { + if (mp_count_bits(key->x) != xbits) + continue; + } + + /* we found a suitable private key key->x */ + found = 1; + } + + if (!found) { + /* key is not found */ + err = CRYPT_PK_NOT_FOUND; + goto error; + } + + /* generate the public key key->y */ + err = mp_exptmod(key->g, key->x, key->p, key->y); + if (err != CRYPT_OK) + goto error; + + /* no error */ + err = CRYPT_OK; + +error: + if (err != CRYPT_OK) + mp_clear_multi(key->x, key->y, NULL); + if (buf) + XFREE(buf); + + return err; +} + +/* + * Free the allocated ram for a DH key + * @param key The key which you wish to free + */ +void dh_free(dh_key *key) +{ + /* + * g and p are not cleared on purpose as they are provided when + * generating the key + */ + if (key->x) { + mp_clear(key->x); + key->x = NULL; + } + if (key->y) { + mp_clear(key->y); + key->y = NULL; + } +} + +/* + * Create a DH shared secret. + * @param private_key The private DH key in the pair + * @param public_key The public DH key in the pair, as a big number + * @param secret The secret (as a big number) + * @return CRYPT_OK if successful + */ +int dh_shared_secret(dh_key *private_key, void *public_key, void *secret) +{ + LTC_ARGCHK(private_key != NULL); + LTC_ARGCHK(public_key != NULL); + LTC_ARGCHK(secret != NULL); + + /* types valid? */ + if (private_key->type != PK_PRIVATE) + return CRYPT_PK_NOT_PRIVATE; + + return mp_exptmod(public_key, private_key->x, private_key->p, secret); +} + +#endif diff --git a/core/lib/libtomcrypt/src/pk/dh/sub.mk b/core/lib/libtomcrypt/src/pk/dh/sub.mk new file mode 100644 index 0000000..7c36ef1 --- /dev/null +++ b/core/lib/libtomcrypt/src/pk/dh/sub.mk @@ -0,0 +1,2 @@ +srcs-y += dh.c +cflags-dh.c-y += -Wno-unused-variable |