You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

240 regels
7.3 KiB

  1. /* ====================================================================
  2. * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * licensing@OpenSSL.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. * ==================================================================== */
  48. #include <openssl/cmac.h>
  49. #include <assert.h>
  50. #include <string.h>
  51. #include <openssl/aes.h>
  52. #include <openssl/cipher.h>
  53. #include <openssl/mem.h>
  54. struct cmac_ctx_st {
  55. EVP_CIPHER_CTX cipher_ctx;
  56. /* k1 and k2 are the CMAC subkeys. See
  57. * https://tools.ietf.org/html/rfc4493#section-2.3 */
  58. uint8_t k1[AES_BLOCK_SIZE];
  59. uint8_t k2[AES_BLOCK_SIZE];
  60. /* Last (possibly partial) scratch */
  61. uint8_t block[AES_BLOCK_SIZE];
  62. /* block_used contains the number of valid bytes in |block|. */
  63. unsigned block_used;
  64. };
  65. static void CMAC_CTX_init(CMAC_CTX *ctx) {
  66. EVP_CIPHER_CTX_init(&ctx->cipher_ctx);
  67. }
  68. static void CMAC_CTX_cleanup(CMAC_CTX *ctx) {
  69. EVP_CIPHER_CTX_cleanup(&ctx->cipher_ctx);
  70. OPENSSL_cleanse(ctx->k1, sizeof(ctx->k1));
  71. OPENSSL_cleanse(ctx->k2, sizeof(ctx->k2));
  72. OPENSSL_cleanse(ctx->block, sizeof(ctx->block));
  73. }
  74. int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len,
  75. const uint8_t *in, size_t in_len) {
  76. const EVP_CIPHER *cipher;
  77. switch (key_len) {
  78. case 16:
  79. cipher = EVP_aes_128_cbc();
  80. break;
  81. case 32:
  82. cipher = EVP_aes_256_cbc();
  83. break;
  84. default:
  85. return 0;
  86. }
  87. size_t scratch_out_len;
  88. CMAC_CTX ctx;
  89. CMAC_CTX_init(&ctx);
  90. const int ok = CMAC_Init(&ctx, key, key_len, cipher, NULL /* engine */) &&
  91. CMAC_Update(&ctx, in, in_len) &&
  92. CMAC_Final(&ctx, out, &scratch_out_len);
  93. CMAC_CTX_cleanup(&ctx);
  94. return ok;
  95. }
  96. CMAC_CTX *CMAC_CTX_new(void) {
  97. CMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
  98. if (ctx != NULL) {
  99. CMAC_CTX_init(ctx);
  100. }
  101. return ctx;
  102. }
  103. void CMAC_CTX_free(CMAC_CTX *ctx) {
  104. if (ctx == NULL) {
  105. return;
  106. }
  107. CMAC_CTX_cleanup(ctx);
  108. OPENSSL_free(ctx);
  109. }
  110. /* binary_field_mul_x treats the 128 bits at |in| as an element of GF(2¹²⁸)
  111. * with a hard-coded reduction polynomial and sets |out| as x times the
  112. * input.
  113. *
  114. * See https://tools.ietf.org/html/rfc4493#section-2.3 */
  115. static void binary_field_mul_x(uint8_t out[16], const uint8_t in[16]) {
  116. unsigned i;
  117. /* Shift |in| to left, including carry. */
  118. for (i = 0; i < 15; i++) {
  119. out[i] = (in[i] << 1) | (in[i+1] >> 7);
  120. }
  121. /* If MSB set fixup with R. */
  122. const uint8_t carry = in[0] >> 7;
  123. out[i] = (in[i] << 1) ^ ((0 - carry) & 0x87);
  124. }
  125. static const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0};
  126. int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len,
  127. const EVP_CIPHER *cipher, ENGINE *engine) {
  128. uint8_t scratch[AES_BLOCK_SIZE];
  129. if (EVP_CIPHER_block_size(cipher) != AES_BLOCK_SIZE ||
  130. EVP_CIPHER_key_length(cipher) != key_len ||
  131. !EVP_EncryptInit_ex(&ctx->cipher_ctx, cipher, NULL, key, kZeroIV) ||
  132. !EVP_Cipher(&ctx->cipher_ctx, scratch, kZeroIV, AES_BLOCK_SIZE) ||
  133. /* Reset context again ready for first data. */
  134. !EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV)) {
  135. return 0;
  136. }
  137. binary_field_mul_x(ctx->k1, scratch);
  138. binary_field_mul_x(ctx->k2, ctx->k1);
  139. ctx->block_used = 0;
  140. return 1;
  141. }
  142. int CMAC_Reset(CMAC_CTX *ctx) {
  143. ctx->block_used = 0;
  144. return EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV);
  145. }
  146. int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len) {
  147. uint8_t scratch[AES_BLOCK_SIZE];
  148. if (ctx->block_used > 0) {
  149. size_t todo = AES_BLOCK_SIZE - ctx->block_used;
  150. if (in_len < todo) {
  151. todo = in_len;
  152. }
  153. memcpy(ctx->block + ctx->block_used, in, todo);
  154. in += todo;
  155. in_len -= todo;
  156. ctx->block_used += todo;
  157. /* If |in_len| is zero then either |ctx->block_used| is less than
  158. * |AES_BLOCK_SIZE|, in which case we can stop here, or |ctx->block_used|
  159. * is exactly |AES_BLOCK_SIZE| but there's no more data to process. In the
  160. * latter case we don't want to process this block now because it might be
  161. * the last block and that block is treated specially. */
  162. if (in_len == 0) {
  163. return 1;
  164. }
  165. assert(ctx->block_used == AES_BLOCK_SIZE);
  166. if (!EVP_Cipher(&ctx->cipher_ctx, scratch, ctx->block, AES_BLOCK_SIZE)) {
  167. return 0;
  168. }
  169. }
  170. /* Encrypt all but one of the remaining blocks. */
  171. while (in_len > AES_BLOCK_SIZE) {
  172. if (!EVP_Cipher(&ctx->cipher_ctx, scratch, in, AES_BLOCK_SIZE)) {
  173. return 0;
  174. }
  175. in += AES_BLOCK_SIZE;
  176. in_len -= AES_BLOCK_SIZE;
  177. }
  178. memcpy(ctx->block, in, in_len);
  179. ctx->block_used = in_len;
  180. return 1;
  181. }
  182. int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len) {
  183. *out_len = AES_BLOCK_SIZE;
  184. if (out == NULL) {
  185. return 1;
  186. }
  187. const uint8_t *mask = ctx->k1;
  188. if (ctx->block_used != AES_BLOCK_SIZE) {
  189. /* If the last block is incomplete, terminate it with a single 'one' bit
  190. * followed by zeros. */
  191. ctx->block[ctx->block_used] = 0x80;
  192. memset(ctx->block + ctx->block_used + 1, 0,
  193. AES_BLOCK_SIZE - (ctx->block_used + 1));
  194. mask = ctx->k2;
  195. }
  196. unsigned i;
  197. for (i = 0; i < AES_BLOCK_SIZE; i++) {
  198. out[i] = ctx->block[i] ^ mask[i];
  199. }
  200. return EVP_Cipher(&ctx->cipher_ctx, out, out, AES_BLOCK_SIZE);
  201. }