aes-omac1.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * One-key CBC MAC (OMAC1) hash with AES
  3. *
  4. * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
  5. *
  6. * This software may be distributed under the terms of the BSD license.
  7. * See README for more details.
  8. */
  9. #include "includes.h"
  10. #include "common.h"
  11. #include "aes.h"
  12. #include "aes_wrap.h"
  13. static void gf_mulx(u8 *pad)
  14. {
  15. int i, carry;
  16. carry = pad[0] & 0x80;
  17. for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
  18. pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
  19. pad[AES_BLOCK_SIZE - 1] <<= 1;
  20. if (carry)
  21. pad[AES_BLOCK_SIZE - 1] ^= 0x87;
  22. }
  23. /**
  24. * omac1_aes_vector - One-Key CBC MAC (OMAC1) hash with AES
  25. * @key: Key for the hash operation
  26. * @key_len: Key length in octets
  27. * @num_elem: Number of elements in the data vector
  28. * @addr: Pointers to the data areas
  29. * @len: Lengths of the data blocks
  30. * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
  31. * Returns: 0 on success, -1 on failure
  32. *
  33. * This is a mode for using block cipher (AES in this case) for authentication.
  34. * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
  35. * (SP) 800-38B.
  36. */
  37. int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
  38. const u8 *addr[], const size_t *len, u8 *mac)
  39. {
  40. void *ctx;
  41. u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
  42. const u8 *pos, *end;
  43. size_t i, e, left, total_len;
  44. if (TEST_FAIL())
  45. return -1;
  46. ctx = aes_encrypt_init(key, key_len);
  47. if (ctx == NULL)
  48. return -1;
  49. os_memset(cbc, 0, AES_BLOCK_SIZE);
  50. total_len = 0;
  51. for (e = 0; e < num_elem; e++)
  52. total_len += len[e];
  53. left = total_len;
  54. e = 0;
  55. pos = addr[0];
  56. end = pos + len[0];
  57. while (left >= AES_BLOCK_SIZE) {
  58. for (i = 0; i < AES_BLOCK_SIZE; i++) {
  59. cbc[i] ^= *pos++;
  60. if (pos >= end) {
  61. /*
  62. * Stop if there are no more bytes to process
  63. * since there are no more entries in the array.
  64. */
  65. if (i + 1 == AES_BLOCK_SIZE &&
  66. left == AES_BLOCK_SIZE)
  67. break;
  68. e++;
  69. pos = addr[e];
  70. end = pos + len[e];
  71. }
  72. }
  73. if (left > AES_BLOCK_SIZE)
  74. aes_encrypt(ctx, cbc, cbc);
  75. left -= AES_BLOCK_SIZE;
  76. }
  77. os_memset(pad, 0, AES_BLOCK_SIZE);
  78. aes_encrypt(ctx, pad, pad);
  79. gf_mulx(pad);
  80. if (left || total_len == 0) {
  81. for (i = 0; i < left; i++) {
  82. cbc[i] ^= *pos++;
  83. if (pos >= end) {
  84. /*
  85. * Stop if there are no more bytes to process
  86. * since there are no more entries in the array.
  87. */
  88. if (i + 1 == left)
  89. break;
  90. e++;
  91. pos = addr[e];
  92. end = pos + len[e];
  93. }
  94. }
  95. cbc[left] ^= 0x80;
  96. gf_mulx(pad);
  97. }
  98. for (i = 0; i < AES_BLOCK_SIZE; i++)
  99. pad[i] ^= cbc[i];
  100. aes_encrypt(ctx, pad, mac);
  101. aes_encrypt_deinit(ctx);
  102. return 0;
  103. }
  104. /**
  105. * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
  106. * @key: 128-bit key for the hash operation
  107. * @num_elem: Number of elements in the data vector
  108. * @addr: Pointers to the data areas
  109. * @len: Lengths of the data blocks
  110. * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
  111. * Returns: 0 on success, -1 on failure
  112. *
  113. * This is a mode for using block cipher (AES in this case) for authentication.
  114. * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
  115. * (SP) 800-38B.
  116. */
  117. int omac1_aes_128_vector(const u8 *key, size_t num_elem,
  118. const u8 *addr[], const size_t *len, u8 *mac)
  119. {
  120. return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
  121. }
  122. /**
  123. * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
  124. * @key: 128-bit key for the hash operation
  125. * @data: Data buffer for which a MAC is determined
  126. * @data_len: Length of data buffer in bytes
  127. * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
  128. * Returns: 0 on success, -1 on failure
  129. *
  130. * This is a mode for using block cipher (AES in this case) for authentication.
  131. * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
  132. * (SP) 800-38B.
  133. */
  134. int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
  135. {
  136. return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
  137. }
  138. /**
  139. * omac1_aes_256 - One-Key CBC MAC (OMAC1) hash with AES-256 (aka AES-CMAC)
  140. * @key: 256-bit key for the hash operation
  141. * @data: Data buffer for which a MAC is determined
  142. * @data_len: Length of data buffer in bytes
  143. * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
  144. * Returns: 0 on success, -1 on failure
  145. *
  146. * This is a mode for using block cipher (AES in this case) for authentication.
  147. * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
  148. * (SP) 800-38B.
  149. */
  150. int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
  151. {
  152. return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
  153. }