cm_pmeth.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  3. * 2010.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * licensing@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. */
  53. #include <stdio.h>
  54. #include "cryptlib.h"
  55. #include <openssl/x509.h>
  56. #include <openssl/x509v3.h>
  57. #include <openssl/evp.h>
  58. #include <openssl/cmac.h>
  59. #include "internal/evp_int.h"
  60. /* The context structure and "key" is simply a CMAC_CTX */
  61. static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
  62. {
  63. ctx->data = CMAC_CTX_new();
  64. if (!ctx->data)
  65. return 0;
  66. ctx->keygen_info_count = 0;
  67. return 1;
  68. }
  69. static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
  70. {
  71. if (!pkey_cmac_init(dst))
  72. return 0;
  73. if (!CMAC_CTX_copy(dst->data, src->data))
  74. return 0;
  75. return 1;
  76. }
  77. static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
  78. {
  79. CMAC_CTX_free(ctx->data);
  80. }
  81. static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
  82. {
  83. CMAC_CTX *cmkey = CMAC_CTX_new();
  84. CMAC_CTX *cmctx = ctx->data;
  85. if (!cmkey)
  86. return 0;
  87. if (!CMAC_CTX_copy(cmkey, cmctx)) {
  88. CMAC_CTX_free(cmkey);
  89. return 0;
  90. }
  91. EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
  92. return 1;
  93. }
  94. static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
  95. {
  96. if (!CMAC_Update(ctx->pctx->data, data, count))
  97. return 0;
  98. return 1;
  99. }
  100. static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
  101. {
  102. EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
  103. mctx->update = int_update;
  104. return 1;
  105. }
  106. static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
  107. EVP_MD_CTX *mctx)
  108. {
  109. return CMAC_Final(ctx->data, sig, siglen);
  110. }
  111. static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
  112. {
  113. CMAC_CTX *cmctx = ctx->data;
  114. switch (type) {
  115. case EVP_PKEY_CTRL_SET_MAC_KEY:
  116. if (!p2 || p1 < 0)
  117. return 0;
  118. if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
  119. return 0;
  120. break;
  121. case EVP_PKEY_CTRL_CIPHER:
  122. if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
  123. return 0;
  124. break;
  125. case EVP_PKEY_CTRL_MD:
  126. if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
  127. (CMAC_CTX *)ctx->pkey->pkey.ptr))
  128. return 0;
  129. if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
  130. return 0;
  131. break;
  132. default:
  133. return -2;
  134. }
  135. return 1;
  136. }
  137. static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx,
  138. const char *type, const char *value)
  139. {
  140. if (!value) {
  141. return 0;
  142. }
  143. if (strcmp(type, "key") == 0) {
  144. void *p = (void *)value;
  145. return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, strlen(p), p);
  146. }
  147. if (strcmp(type, "cipher") == 0) {
  148. const EVP_CIPHER *c;
  149. c = EVP_get_cipherbyname(value);
  150. if (!c)
  151. return 0;
  152. return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
  153. }
  154. if (strcmp(type, "hexkey") == 0) {
  155. unsigned char *key;
  156. int r;
  157. long keylen;
  158. key = string_to_hex(value, &keylen);
  159. if (!key)
  160. return 0;
  161. r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
  162. OPENSSL_free(key);
  163. return r;
  164. }
  165. return -2;
  166. }
  167. const EVP_PKEY_METHOD cmac_pkey_meth = {
  168. EVP_PKEY_CMAC,
  169. EVP_PKEY_FLAG_SIGCTX_CUSTOM,
  170. pkey_cmac_init,
  171. pkey_cmac_copy,
  172. pkey_cmac_cleanup,
  173. 0, 0,
  174. 0,
  175. pkey_cmac_keygen,
  176. 0, 0,
  177. 0, 0,
  178. 0, 0,
  179. cmac_signctx_init,
  180. cmac_signctx,
  181. 0, 0,
  182. 0, 0,
  183. 0, 0,
  184. 0, 0,
  185. pkey_cmac_ctrl,
  186. pkey_cmac_ctrl_str
  187. };