aes-unwrap.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * AES key unwrap (RFC3394)
  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. /**
  14. * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (RFC3394)
  15. * @kek: Key encryption key (KEK)
  16. * @kek_len: Length of KEK in octets
  17. * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
  18. * bytes
  19. * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
  20. * @plain: Plaintext key, n * 64 bits
  21. * Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
  22. */
  23. int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
  24. u8 *plain)
  25. {
  26. u8 a[8], *r, b[AES_BLOCK_SIZE];
  27. int i, j;
  28. void *ctx;
  29. unsigned int t;
  30. /* 1) Initialize variables. */
  31. os_memcpy(a, cipher, 8);
  32. r = plain;
  33. os_memcpy(r, cipher + 8, 8 * n);
  34. ctx = aes_decrypt_init(kek, kek_len);
  35. if (ctx == NULL)
  36. return -1;
  37. /* 2) Compute intermediate values.
  38. * For j = 5 to 0
  39. * For i = n to 1
  40. * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
  41. * A = MSB(64, B)
  42. * R[i] = LSB(64, B)
  43. */
  44. for (j = 5; j >= 0; j--) {
  45. r = plain + (n - 1) * 8;
  46. for (i = n; i >= 1; i--) {
  47. os_memcpy(b, a, 8);
  48. t = n * j + i;
  49. b[7] ^= t;
  50. b[6] ^= t >> 8;
  51. b[5] ^= t >> 16;
  52. b[4] ^= t >> 24;
  53. os_memcpy(b + 8, r, 8);
  54. aes_decrypt(ctx, b, b);
  55. os_memcpy(a, b, 8);
  56. os_memcpy(r, b + 8, 8);
  57. r -= 8;
  58. }
  59. }
  60. aes_decrypt_deinit(ctx);
  61. /* 3) Output results.
  62. *
  63. * These are already in @plain due to the location of temporary
  64. * variables. Just verify that the IV matches with the expected value.
  65. */
  66. for (i = 0; i < 8; i++) {
  67. if (a[i] != 0xa6)
  68. return -1;
  69. }
  70. return 0;
  71. }