summaryrefslogtreecommitdiff
path: root/core/lib/libtomcrypt/src/pk/dh
diff options
context:
space:
mode:
Diffstat (limited to 'core/lib/libtomcrypt/src/pk/dh')
-rw-r--r--core/lib/libtomcrypt/src/pk/dh/dh.c217
-rw-r--r--core/lib/libtomcrypt/src/pk/dh/sub.mk2
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