aes-siv.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * AES SIV (RFC 5297)
  3. * Copyright (c) 2013 Cozybit, Inc.
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "aes.h"
  11. #include "aes_wrap.h"
  12. #include "aes_siv.h"
  13. static const u8 zero[AES_BLOCK_SIZE];
  14. static void dbl(u8 *pad)
  15. {
  16. int i, carry;
  17. carry = pad[0] & 0x80;
  18. for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
  19. pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
  20. pad[AES_BLOCK_SIZE - 1] <<= 1;
  21. if (carry)
  22. pad[AES_BLOCK_SIZE - 1] ^= 0x87;
  23. }
  24. static void xor(u8 *a, const u8 *b)
  25. {
  26. int i;
  27. for (i = 0; i < AES_BLOCK_SIZE; i++)
  28. *a++ ^= *b++;
  29. }
  30. static void xorend(u8 *a, int alen, const u8 *b, int blen)
  31. {
  32. int i;
  33. if (alen < blen)
  34. return;
  35. for (i = 0; i < blen; i++)
  36. a[alen - blen + i] ^= b[i];
  37. }
  38. static void pad_block(u8 *pad, const u8 *addr, size_t len)
  39. {
  40. os_memset(pad, 0, AES_BLOCK_SIZE);
  41. os_memcpy(pad, addr, len);
  42. if (len < AES_BLOCK_SIZE)
  43. pad[len] = 0x80;
  44. }
  45. static int aes_s2v(const u8 *key, size_t key_len,
  46. size_t num_elem, const u8 *addr[], size_t *len, u8 *mac)
  47. {
  48. u8 tmp[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
  49. u8 *buf = NULL;
  50. int ret;
  51. size_t i;
  52. const u8 *data[1];
  53. size_t data_len[1];
  54. if (!num_elem) {
  55. os_memcpy(tmp, zero, sizeof(zero));
  56. tmp[AES_BLOCK_SIZE - 1] = 1;
  57. data[0] = tmp;
  58. data_len[0] = sizeof(tmp);
  59. return omac1_aes_vector(key, key_len, 1, data, data_len, mac);
  60. }
  61. data[0] = zero;
  62. data_len[0] = sizeof(zero);
  63. ret = omac1_aes_vector(key, key_len, 1, data, data_len, tmp);
  64. if (ret)
  65. return ret;
  66. for (i = 0; i < num_elem - 1; i++) {
  67. ret = omac1_aes_vector(key, key_len, 1, &addr[i], &len[i],
  68. tmp2);
  69. if (ret)
  70. return ret;
  71. dbl(tmp);
  72. xor(tmp, tmp2);
  73. }
  74. if (len[i] >= AES_BLOCK_SIZE) {
  75. buf = os_malloc(len[i]);
  76. if (!buf)
  77. return -ENOMEM;
  78. os_memcpy(buf, addr[i], len[i]);
  79. xorend(buf, len[i], tmp, AES_BLOCK_SIZE);
  80. data[0] = buf;
  81. ret = omac1_aes_vector(key, key_len, 1, data, &len[i], mac);
  82. bin_clear_free(buf, len[i]);
  83. return ret;
  84. }
  85. dbl(tmp);
  86. pad_block(tmp2, addr[i], len[i]);
  87. xor(tmp, tmp2);
  88. data[0] = tmp;
  89. data_len[0] = sizeof(tmp);
  90. return omac1_aes_vector(key, key_len, 1, data, data_len, mac);
  91. }
  92. int aes_siv_encrypt(const u8 *key, size_t key_len,
  93. const u8 *pw, size_t pwlen,
  94. size_t num_elem, const u8 *addr[], const size_t *len,
  95. u8 *out)
  96. {
  97. const u8 *_addr[6];
  98. size_t _len[6];
  99. const u8 *k1, *k2;
  100. u8 v[AES_BLOCK_SIZE];
  101. size_t i;
  102. u8 *iv, *crypt_pw;
  103. if (num_elem > ARRAY_SIZE(_addr) - 1 ||
  104. (key_len != 32 && key_len != 48 && key_len != 64))
  105. return -1;
  106. key_len /= 2;
  107. k1 = key;
  108. k2 = key + key_len;
  109. for (i = 0; i < num_elem; i++) {
  110. _addr[i] = addr[i];
  111. _len[i] = len[i];
  112. }
  113. _addr[num_elem] = pw;
  114. _len[num_elem] = pwlen;
  115. if (aes_s2v(k1, key_len, num_elem + 1, _addr, _len, v))
  116. return -1;
  117. iv = out;
  118. crypt_pw = out + AES_BLOCK_SIZE;
  119. os_memcpy(iv, v, AES_BLOCK_SIZE);
  120. os_memcpy(crypt_pw, pw, pwlen);
  121. /* zero out 63rd and 31st bits of ctr (from right) */
  122. v[8] &= 0x7f;
  123. v[12] &= 0x7f;
  124. return aes_ctr_encrypt(k2, key_len, v, crypt_pw, pwlen);
  125. }
  126. int aes_siv_decrypt(const u8 *key, size_t key_len,
  127. const u8 *iv_crypt, size_t iv_c_len,
  128. size_t num_elem, const u8 *addr[], const size_t *len,
  129. u8 *out)
  130. {
  131. const u8 *_addr[6];
  132. size_t _len[6];
  133. const u8 *k1, *k2;
  134. size_t crypt_len;
  135. size_t i;
  136. int ret;
  137. u8 iv[AES_BLOCK_SIZE];
  138. u8 check[AES_BLOCK_SIZE];
  139. if (iv_c_len < AES_BLOCK_SIZE || num_elem > ARRAY_SIZE(_addr) - 1 ||
  140. (key_len != 32 && key_len != 48 && key_len != 64))
  141. return -1;
  142. crypt_len = iv_c_len - AES_BLOCK_SIZE;
  143. key_len /= 2;
  144. k1 = key;
  145. k2 = key + key_len;
  146. for (i = 0; i < num_elem; i++) {
  147. _addr[i] = addr[i];
  148. _len[i] = len[i];
  149. }
  150. _addr[num_elem] = out;
  151. _len[num_elem] = crypt_len;
  152. os_memcpy(iv, iv_crypt, AES_BLOCK_SIZE);
  153. os_memcpy(out, iv_crypt + AES_BLOCK_SIZE, crypt_len);
  154. iv[8] &= 0x7f;
  155. iv[12] &= 0x7f;
  156. ret = aes_ctr_encrypt(k2, key_len, iv, out, crypt_len);
  157. if (ret)
  158. return ret;
  159. ret = aes_s2v(k1, key_len, num_elem + 1, _addr, _len, check);
  160. if (ret)
  161. return ret;
  162. if (os_memcmp(check, iv_crypt, AES_BLOCK_SIZE) == 0)
  163. return 0;
  164. return -1;
  165. }