rijndael-padlock.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* Padlock accelerated AES for Libgcrypt
  2. * Copyright (C) 2000, 2001, 2002, 2003, 2007,
  3. * 2008, 2011, 2012 Free Software Foundation, Inc.
  4. *
  5. * This file is part of Libgcrypt.
  6. *
  7. * Libgcrypt is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * Libgcrypt is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <config.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h> /* for memcmp() */
  24. #include "types.h" /* for byte and u32 typedefs */
  25. #include "g10lib.h"
  26. #include "cipher.h"
  27. #include "bufhelp.h"
  28. #include "rijndael-internal.h"
  29. #ifdef USE_PADLOCK
  30. /* Encrypt or decrypt one block using the padlock engine. A and B may
  31. be the same. */
  32. static unsigned int
  33. do_padlock (const RIJNDAEL_context *ctx, unsigned char *bx,
  34. const unsigned char *ax, int decrypt_flag)
  35. {
  36. /* BX and AX are not necessary correctly aligned. Thus we need to
  37. copy them here. */
  38. unsigned char a[16] __attribute__ ((aligned (16)));
  39. unsigned char b[16] __attribute__ ((aligned (16)));
  40. unsigned int cword[4] __attribute__ ((aligned (16)));
  41. unsigned char *pa = a;
  42. unsigned char *pb = b;
  43. int blocks;
  44. /* The control word fields are:
  45. 127:12 11:10 9 8 7 6 5 4 3:0
  46. RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND */
  47. cword[0] = (ctx->rounds & 15); /* (The mask is just a safeguard.) */
  48. cword[1] = 0;
  49. cword[2] = 0;
  50. cword[3] = 0;
  51. if (decrypt_flag)
  52. cword[0] |= 0x00000200;
  53. memcpy (a, ax, 16);
  54. blocks = 1; /* Init counter for just one block. */
  55. #ifdef __x86_64__
  56. asm volatile
  57. ("pushfq\n\t" /* Force key reload. */
  58. "popfq\n\t"
  59. ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
  60. : "+S" (pa), "+D" (pb), "+c" (blocks)
  61. : "d" (cword), "b" (ctx->padlockkey)
  62. : "cc", "memory"
  63. );
  64. #else
  65. asm volatile
  66. ("pushfl\n\t" /* Force key reload. */
  67. "popfl\n\t"
  68. "xchg %4, %%ebx\n\t" /* Load key. */
  69. ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
  70. "xchg %4, %%ebx\n" /* Restore GOT register. */
  71. : "+S" (pa), "+D" (pb), "+c" (blocks)
  72. : "d" (cword), "r" (ctx->padlockkey)
  73. : "cc", "memory"
  74. );
  75. #endif
  76. memcpy (bx, b, 16);
  77. return (48 + 15 /* possible padding for alignment */);
  78. }
  79. unsigned int
  80. _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx,
  81. unsigned char *bx, const unsigned char *ax)
  82. {
  83. return do_padlock(ctx, bx, ax, 0);
  84. }
  85. unsigned int
  86. _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx,
  87. unsigned char *bx, const unsigned char *ax)
  88. {
  89. return do_padlock(ctx, bx, ax, 1);
  90. }
  91. void
  92. _gcry_aes_padlock_prepare_decryption (RIJNDAEL_context *ctx)
  93. {
  94. /* Padlock does not need decryption subkeys. */
  95. (void)ctx;
  96. }
  97. #endif /* USE_PADLOCK */