cipher_des.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright 2019 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. #include "prov/ciphercommon.h"
  10. #include "cipher_des.h"
  11. #include <openssl/rand.h>
  12. #include "prov/implementations.h"
  13. #include "prov/providercommonerr.h"
  14. /* TODO(3.0) Figure out what flags need to be here */
  15. #define DES_FLAGS (EVP_CIPH_RAND_KEY)
  16. static OSSL_OP_cipher_freectx_fn des_freectx;
  17. static OSSL_OP_cipher_encrypt_init_fn des_einit;
  18. static OSSL_OP_cipher_decrypt_init_fn des_dinit;
  19. static OSSL_OP_cipher_get_ctx_params_fn des_get_ctx_params;
  20. static OSSL_OP_cipher_gettable_ctx_params_fn des_gettable_ctx_params;
  21. static void *des_newctx(void *provctx, size_t kbits, size_t blkbits,
  22. size_t ivbits, unsigned int mode, uint64_t flags,
  23. const PROV_CIPHER_HW *hw)
  24. {
  25. PROV_DES_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
  26. if (ctx != NULL)
  27. cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, hw,
  28. provctx);
  29. return ctx;
  30. }
  31. static void des_freectx(void *vctx)
  32. {
  33. PROV_DES_CTX *ctx = (PROV_DES_CTX *)vctx;
  34. OPENSSL_clear_free(ctx, sizeof(*ctx));
  35. }
  36. static int des_init(void *vctx, const unsigned char *key, size_t keylen,
  37. const unsigned char *iv, size_t ivlen, int enc)
  38. {
  39. PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
  40. ctx->enc = enc;
  41. if (iv != NULL) {
  42. if (!cipher_generic_initiv(ctx, iv, ivlen))
  43. return 0;
  44. }
  45. if (key != NULL) {
  46. if (keylen != ctx->keylen) {
  47. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
  48. return 0;
  49. }
  50. return ctx->hw->init(ctx, key, keylen);
  51. }
  52. return 1;
  53. }
  54. static int des_einit(void *vctx, const unsigned char *key, size_t keylen,
  55. const unsigned char *iv, size_t ivlen)
  56. {
  57. return des_init(vctx, key, keylen, iv, ivlen, 1);
  58. }
  59. static int des_dinit(void *vctx, const unsigned char *key, size_t keylen,
  60. const unsigned char *iv, size_t ivlen)
  61. {
  62. return des_init(vctx, key, keylen, iv, ivlen, 0);
  63. }
  64. static int des_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
  65. {
  66. DES_cblock *deskey = ptr;
  67. size_t kl = ctx->keylen;
  68. if (kl == 0 || RAND_priv_bytes_ex(ctx->libctx, ptr, kl) <= 0)
  69. return 0;
  70. DES_set_odd_parity(deskey);
  71. return 1;
  72. }
  73. CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(des)
  74. OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0),
  75. CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(des)
  76. static int des_get_ctx_params(void *vctx, OSSL_PARAM params[])
  77. {
  78. PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
  79. OSSL_PARAM *p;
  80. if (!cipher_generic_get_ctx_params(vctx, params))
  81. return 0;
  82. p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY);
  83. if (p != NULL && !des_generatekey(ctx, p->data)) {
  84. ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY);
  85. return 0;
  86. }
  87. return 1;
  88. }
  89. #define IMPLEMENT_des_cipher(type, lcmode, UCMODE, flags, \
  90. kbits, blkbits, ivbits, block) \
  91. static OSSL_OP_cipher_newctx_fn type##_##lcmode##_newctx; \
  92. static void *des_##lcmode##_newctx(void *provctx) \
  93. { \
  94. return des_newctx(provctx, kbits, blkbits, ivbits, \
  95. EVP_CIPH_##UCMODE##_MODE, flags, \
  96. PROV_CIPHER_HW_des_##lcmode()); \
  97. } \
  98. static OSSL_OP_cipher_get_params_fn des_##lcmode##_get_params; \
  99. static int des_##lcmode##_get_params(OSSL_PARAM params[]) \
  100. { \
  101. return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \
  102. kbits, blkbits, ivbits); \
  103. } \
  104. const OSSL_DISPATCH des_##lcmode##_functions[] = { \
  105. { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))des_einit }, \
  106. { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))des_dinit }, \
  107. { OSSL_FUNC_CIPHER_UPDATE, \
  108. (void (*)(void))cipher_generic_##block##_update }, \
  109. { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##block##_final },\
  110. { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \
  111. { OSSL_FUNC_CIPHER_NEWCTX, \
  112. (void (*)(void))des_##lcmode##_newctx }, \
  113. { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))des_freectx }, \
  114. { OSSL_FUNC_CIPHER_GET_PARAMS, \
  115. (void (*)(void))des_##lcmode##_get_params }, \
  116. { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
  117. (void (*)(void))cipher_generic_gettable_params }, \
  118. { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))des_get_ctx_params }, \
  119. { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
  120. (void (*)(void))des_gettable_ctx_params }, \
  121. { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
  122. (void (*)(void))cipher_generic_set_ctx_params }, \
  123. { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
  124. (void (*)(void))cipher_generic_settable_ctx_params }, \
  125. { 0, NULL } \
  126. }
  127. /* des_ecb_functions */
  128. IMPLEMENT_des_cipher(des, ecb, ECB, DES_FLAGS, 64, 64, 0, block);
  129. /* des_cbc_functions */
  130. IMPLEMENT_des_cipher(des, cbc, CBC, DES_FLAGS, 64, 64, 64, block);
  131. /* des_ofb64_functions */
  132. IMPLEMENT_des_cipher(des, ofb64, OFB, DES_FLAGS, 64, 8, 64, stream);
  133. /* des_cfb64_functions */
  134. IMPLEMENT_des_cipher(des, cfb64, CFB, DES_FLAGS, 64, 8, 64, stream);
  135. /* des_cfb1_functions */
  136. IMPLEMENT_des_cipher(des, cfb1, CFB, DES_FLAGS, 64, 8, 64, stream);
  137. /* des_cfb8_functions */
  138. IMPLEMENT_des_cipher(des, cfb8, CFB, DES_FLAGS, 64, 8, 64, stream);