p12_key.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include <openssl/pkcs12.h>
  12. #include <openssl/bn.h>
  13. #include <openssl/trace.h>
  14. /* PKCS12 compatible key/IV generation */
  15. #ifndef min
  16. # define min(a,b) ((a) < (b) ? (a) : (b))
  17. #endif
  18. int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
  19. int saltlen, int id, int iter, int n,
  20. unsigned char *out, const EVP_MD *md_type)
  21. {
  22. int ret;
  23. unsigned char *unipass;
  24. int uniplen;
  25. if (pass == NULL) {
  26. unipass = NULL;
  27. uniplen = 0;
  28. } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
  29. PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE);
  30. return 0;
  31. }
  32. ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
  33. id, iter, n, out, md_type);
  34. if (ret <= 0)
  35. return 0;
  36. OPENSSL_clear_free(unipass, uniplen);
  37. return ret;
  38. }
  39. int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
  40. int saltlen, int id, int iter, int n,
  41. unsigned char *out, const EVP_MD *md_type)
  42. {
  43. int ret;
  44. unsigned char *unipass;
  45. int uniplen;
  46. if (pass == NULL) {
  47. unipass = NULL;
  48. uniplen = 0;
  49. } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) {
  50. PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UTF8, ERR_R_MALLOC_FAILURE);
  51. return 0;
  52. }
  53. ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
  54. id, iter, n, out, md_type);
  55. if (ret <= 0)
  56. return 0;
  57. OPENSSL_clear_free(unipass, uniplen);
  58. return ret;
  59. }
  60. int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
  61. int saltlen, int id, int iter, int n,
  62. unsigned char *out, const EVP_MD *md_type)
  63. {
  64. unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL;
  65. int Slen, Plen, Ilen;
  66. int i, j, u, v;
  67. int ret = 0;
  68. EVP_MD_CTX *ctx = NULL;
  69. unsigned char *tmpout = out;
  70. int tmpn = n;
  71. ctx = EVP_MD_CTX_new();
  72. if (ctx == NULL)
  73. goto err;
  74. OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
  75. BIO_printf(trc_out, "PKCS12_key_gen_uni(): ID %d, ITER %d\n", id, iter);
  76. BIO_printf(trc_out, "Password (length %d):\n", passlen);
  77. BIO_hex_string(trc_out, 0, passlen, pass, passlen);
  78. BIO_printf(trc_out, "\n");
  79. BIO_printf(trc_out, "Salt (length %d):\n", saltlen);
  80. BIO_hex_string(trc_out, 0, saltlen, salt, saltlen);
  81. BIO_printf(trc_out, "\n");
  82. } OSSL_TRACE_END(PKCS12_KEYGEN);
  83. v = EVP_MD_block_size(md_type);
  84. u = EVP_MD_size(md_type);
  85. if (u < 0 || v <= 0)
  86. goto err;
  87. D = OPENSSL_malloc(v);
  88. Ai = OPENSSL_malloc(u);
  89. B = OPENSSL_malloc(v + 1);
  90. Slen = v * ((saltlen + v - 1) / v);
  91. if (passlen)
  92. Plen = v * ((passlen + v - 1) / v);
  93. else
  94. Plen = 0;
  95. Ilen = Slen + Plen;
  96. I = OPENSSL_malloc(Ilen);
  97. if (D == NULL || Ai == NULL || B == NULL || I == NULL)
  98. goto err;
  99. for (i = 0; i < v; i++)
  100. D[i] = id;
  101. p = I;
  102. for (i = 0; i < Slen; i++)
  103. *p++ = salt[i % saltlen];
  104. for (i = 0; i < Plen; i++)
  105. *p++ = pass[i % passlen];
  106. for (;;) {
  107. if (!EVP_DigestInit_ex(ctx, md_type, NULL)
  108. || !EVP_DigestUpdate(ctx, D, v)
  109. || !EVP_DigestUpdate(ctx, I, Ilen)
  110. || !EVP_DigestFinal_ex(ctx, Ai, NULL))
  111. goto err;
  112. for (j = 1; j < iter; j++) {
  113. if (!EVP_DigestInit_ex(ctx, md_type, NULL)
  114. || !EVP_DigestUpdate(ctx, Ai, u)
  115. || !EVP_DigestFinal_ex(ctx, Ai, NULL))
  116. goto err;
  117. }
  118. memcpy(out, Ai, min(n, u));
  119. if (u >= n) {
  120. OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
  121. BIO_printf(trc_out, "Output KEY (length %d)\n", tmpn);
  122. BIO_hex_string(trc_out, 0, tmpn, tmpout, tmpn);
  123. BIO_printf(trc_out, "\n");
  124. } OSSL_TRACE_END(PKCS12_KEYGEN);
  125. ret = 1;
  126. goto end;
  127. }
  128. n -= u;
  129. out += u;
  130. for (j = 0; j < v; j++)
  131. B[j] = Ai[j % u];
  132. for (j = 0; j < Ilen; j += v) {
  133. int k;
  134. unsigned char *Ij = I + j;
  135. uint16_t c = 1;
  136. /* Work out Ij = Ij + B + 1 */
  137. for (k = v - 1; k >= 0; k--) {
  138. c += Ij[k] + B[k];
  139. Ij[k] = (unsigned char)c;
  140. c >>= 8;
  141. }
  142. }
  143. }
  144. err:
  145. PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);
  146. end:
  147. OPENSSL_free(Ai);
  148. OPENSSL_free(B);
  149. OPENSSL_free(D);
  150. OPENSSL_free(I);
  151. EVP_MD_CTX_free(ctx);
  152. return ret;
  153. }