summaryrefslogtreecommitdiffstats
path: root/crypto/pkcs12/p12_key.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>1999-03-28 23:17:34 +0000
committerDr. Stephen Henson <steve@openssl.org>1999-03-28 23:17:34 +0000
commit8d8c7266d4de9887fb0190a0770df9dc254a16a3 (patch)
tree53266f3f48875973f3c7f96abf912c5084155a23 /crypto/pkcs12/p12_key.c
parentcfcefcbe2aff81c1735c788ca6ae26b7c16cc453 (diff)
Yet more PKCS#12 integration: add lots of files under crypto/pkcs12 and add
them to the build environment.
Diffstat (limited to 'crypto/pkcs12/p12_key.c')
-rw-r--r--crypto/pkcs12/p12_key.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c
new file mode 100644
index 0000000000..f1506ba1cd
--- /dev/null
+++ b/crypto/pkcs12/p12_key.c
@@ -0,0 +1,190 @@
+/* p12_key.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. 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.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <err.h>
+#include <bn.h>
+#include "pkcs12.h"
+
+
+/* Uncomment out this line to get debugging info about key generation */
+/*#define DEBUG_KEYGEN*/
+#ifdef DEBUG_KEYGEN
+#include <bio.h>
+extern BIO *bio_err;
+void h__dump (unsigned char *p, int len);
+#endif
+
+/* PKCS12 compatible key/IV generation */
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+int PKCS12_key_gen_asc (pass, passlen, salt, saltlen, id, iter, n, out, md_type)
+unsigned char *pass, *salt, *out;
+int passlen, saltlen, id, iter, n;
+EVP_MD *md_type;
+{
+ int ret;
+ unsigned char *unipass;
+ int uniplen;
+ if (!asc2uni (pass, &unipass, &uniplen)) {
+ PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ret = PKCS12_key_gen_uni (unipass, uniplen, salt, saltlen,
+ id, iter, n, out, md_type);
+ memset(unipass, 0, uniplen); /* Clear password from memory */
+ Free(unipass);
+ return ret;
+}
+
+int PKCS12_key_gen_uni (pass, passlen, salt, saltlen, id, iter, n, out, md_type)
+unsigned char *pass, *salt, *out;
+int passlen, saltlen, id, iter, n;
+EVP_MD *md_type;
+{
+ unsigned char *B, *D, *I, *p, *Ai;
+ int Slen, Plen, Ilen;
+ int i, j, u, v;
+ BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */
+ EVP_MD_CTX ctx;
+#ifdef DEBUG_KEYGEN
+ unsigned char *tmpout = out;
+ int tmpn = n;
+ BIO_printf (bio_err, "KEYGEN DEBUG\n");
+ BIO_printf (bio_err, "ID %d, ITER %d\n", id, iter);
+ BIO_printf (bio_err, "Password (length %d):\n", passlen);
+ h__dump (pass, passlen);
+ BIO_printf (bio_err, "Salt (length %d):\n", saltlen);
+ h__dump (salt, saltlen);
+ BIO_printf (bio_err, "ID %d, ITER %d\n\n", id, iter);
+#endif
+ v = EVP_MD_block_size (md_type);
+ u = EVP_MD_size (md_type);
+ D = Malloc (v);
+ Ai = Malloc (u);
+ B = Malloc (v + 1);
+ Slen = v * ((saltlen+v-1)/v);
+ Plen = v * ((passlen+v-1)/v);
+ Ilen = Slen + Plen;
+ I = Malloc (Ilen);
+ Ij = BN_new();
+ Bpl1 = BN_new();
+ if (!D || !Ai || !B || !I || !Ij || !Bpl1) {
+ PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ for (i = 0; i < v; i++) D[i] = id;
+ p = I;
+ for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen];
+ for (i = 0; i < Plen; i++) *p++ = pass[i % passlen];
+ for (;;) {
+ EVP_DigestInit (&ctx, md_type);
+ EVP_DigestUpdate (&ctx, D, v);
+ EVP_DigestUpdate (&ctx, I, Ilen);
+ EVP_DigestFinal (&ctx, Ai, NULL);
+ for (j = 1; j < iter; j++) {
+ EVP_DigestInit (&ctx, md_type);
+ EVP_DigestUpdate (&ctx, Ai, u);
+ EVP_DigestFinal (&ctx, Ai, NULL);
+ }
+ memcpy (out, Ai, min (n, u));
+ if (u >= n) {
+ Free (Ai);
+ Free (B);
+ Free (D);
+ Free (I);
+ BN_free (Ij);
+ BN_free (Bpl1);
+#ifdef DEBUG_KEYGEN
+ BIO_printf (bio_err, "Output KEY (length %d)\n", tmpn);
+ h__dump (tmpout, tmpn);
+#endif
+ return 1;
+ }
+ n -= u;
+ out += u;
+ for (j = 0; j < v; j++) B[j] = Ai[j % u];
+ /* Work out B + 1 first then can use B as tmp space */
+ BN_bin2bn (B, v, Bpl1);
+ BN_add_word (Bpl1, 1);
+ for (j = 0; j < Ilen ; j+=v) {
+ BN_bin2bn (I + j, v, Ij);
+ BN_add (Ij, Ij, Bpl1);
+ BN_bn2bin (Ij, B);
+ /* If more than 2^(v*8) - 1 cut off MSB */
+ if (BN_num_bytes (Ij) > v) {
+ BN_bn2bin (Ij, B);
+ memcpy (I + j, B + 1, v);
+ } else BN_bn2bin (Ij, I + j);
+ }
+ }
+ return 0; /* This can't happen */
+}
+#ifdef DEBUG_KEYGEN
+void h__dump (p, len)
+unsigned char *p;
+int len;
+{
+ for (; len --; p++) BIO_printf (bio_err, "%02X", *p);
+ BIO_printf (bio_err, "\n");
+}
+#endif