cipher_des_hw.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /*
  10. * DES low level APIs are deprecated for public use, but still ok for internal
  11. * use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include "prov/ciphercommon.h"
  15. #include "cipher_des.h"
  16. static int cipher_hw_des_initkey(PROV_CIPHER_CTX *ctx,
  17. const unsigned char *key, size_t keylen)
  18. {
  19. PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
  20. DES_cblock *deskey = (DES_cblock *)key;
  21. DES_key_schedule *ks = &dctx->dks.ks;
  22. dctx->dstream.cbc = NULL;
  23. #if defined(SPARC_DES_CAPABLE)
  24. if (SPARC_DES_CAPABLE) {
  25. if (ctx->mode == EVP_CIPH_CBC_MODE) {
  26. des_t4_key_expand(&deskey[0], ks);
  27. dctx->dstream.cbc = ctx->enc ? des_t4_cbc_encrypt :
  28. des_t4_cbc_decrypt;
  29. return 1;
  30. }
  31. }
  32. #endif
  33. DES_set_key_unchecked(deskey, ks);
  34. return 1;
  35. }
  36. static void cipher_hw_des_copyctx(PROV_CIPHER_CTX *dst,
  37. const PROV_CIPHER_CTX *src)
  38. {
  39. PROV_DES_CTX *sctx = (PROV_DES_CTX *)src;
  40. PROV_DES_CTX *dctx = (PROV_DES_CTX *)dst;
  41. *dctx = *sctx;
  42. dst->ks = &dctx->dks.ks;
  43. }
  44. static int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
  45. const unsigned char *in, size_t len)
  46. {
  47. size_t i, bl = ctx->blocksize;
  48. DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
  49. if (len < bl)
  50. return 1;
  51. for (i = 0, len -= bl; i <= len; i += bl)
  52. DES_ecb_encrypt((const_DES_cblock *)(in + i),
  53. (const_DES_cblock *)(out + i), key, ctx->enc);
  54. return 1;
  55. }
  56. static int cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
  57. const unsigned char *in, size_t len)
  58. {
  59. PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
  60. DES_key_schedule *key = &(dctx->dks.ks);
  61. if (dctx->dstream.cbc != NULL) {
  62. (*dctx->dstream.cbc) (in, out, len, key, ctx->iv);
  63. return 1;
  64. }
  65. while (len >= MAXCHUNK) {
  66. DES_ncbc_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv,
  67. ctx->enc);
  68. len -= MAXCHUNK;
  69. in += MAXCHUNK;
  70. out += MAXCHUNK;
  71. }
  72. if (len > 0)
  73. DES_ncbc_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv,
  74. ctx->enc);
  75. return 1;
  76. }
  77. static int cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
  78. const unsigned char *in, size_t len)
  79. {
  80. int num = ctx->num;
  81. DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
  82. while (len >= MAXCHUNK) {
  83. DES_ofb64_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, &num);
  84. len -= MAXCHUNK;
  85. in += MAXCHUNK;
  86. out += MAXCHUNK;
  87. }
  88. if (len > 0) {
  89. DES_ofb64_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, &num);
  90. }
  91. ctx->num = num;
  92. return 1;
  93. }
  94. static int cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
  95. const unsigned char *in, size_t len)
  96. {
  97. size_t chunk = MAXCHUNK;
  98. DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
  99. int num = ctx->num;
  100. if (len < chunk)
  101. chunk = len;
  102. while (len > 0 && len >= chunk) {
  103. DES_cfb64_encrypt(in, out, (long)chunk, key, (DES_cblock *)ctx->iv,
  104. &num, ctx->enc);
  105. len -= chunk;
  106. in += chunk;
  107. out += chunk;
  108. if (len < chunk)
  109. chunk = len;
  110. }
  111. ctx->num = num;
  112. return 1;
  113. }
  114. /*
  115. * Although we have a CFB-r implementation for DES, it doesn't pack the right
  116. * way, so wrap it here
  117. */
  118. static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
  119. const unsigned char *in, size_t inl)
  120. {
  121. size_t n, chunk = MAXCHUNK / 8;
  122. DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
  123. unsigned char c[1], d[1];
  124. if (inl < chunk)
  125. chunk = inl;
  126. while (inl && inl >= chunk) {
  127. for (n = 0; n < chunk * 8; ++n) {
  128. c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
  129. DES_cfb_encrypt(c, d, 1, 1, key, (DES_cblock *)ctx->iv, ctx->enc);
  130. out[n / 8] =
  131. (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
  132. ((d[0] & 0x80) >> (unsigned int)(n % 8));
  133. }
  134. inl -= chunk;
  135. in += chunk;
  136. out += chunk;
  137. if (inl < chunk)
  138. chunk = inl;
  139. }
  140. return 1;
  141. }
  142. static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
  143. const unsigned char *in, size_t inl)
  144. {
  145. DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
  146. while (inl >= MAXCHUNK) {
  147. DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key,
  148. (DES_cblock *)ctx->iv, ctx->enc);
  149. inl -= MAXCHUNK;
  150. in += MAXCHUNK;
  151. out += MAXCHUNK;
  152. }
  153. if (inl > 0)
  154. DES_cfb_encrypt(in, out, 8, (long)inl, key,
  155. (DES_cblock *)ctx->iv, ctx->enc);
  156. return 1;
  157. }
  158. #define PROV_CIPHER_HW_des_mode(mode) \
  159. static const PROV_CIPHER_HW des_##mode = { \
  160. cipher_hw_des_initkey, \
  161. cipher_hw_des_##mode##_cipher, \
  162. cipher_hw_des_copyctx \
  163. }; \
  164. const PROV_CIPHER_HW *PROV_CIPHER_HW_des_##mode(void) \
  165. { \
  166. return &des_##mode; \
  167. }
  168. PROV_CIPHER_HW_des_mode(ecb)
  169. PROV_CIPHER_HW_des_mode(cbc)
  170. PROV_CIPHER_HW_des_mode(ofb64)
  171. PROV_CIPHER_HW_des_mode(cfb64)
  172. PROV_CIPHER_HW_des_mode(cfb1)
  173. PROV_CIPHER_HW_des_mode(cfb8)