evp_skey_test.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright 2024-2025 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 <openssl/provider.h>
  10. #include <openssl/params.h>
  11. #include <openssl/param_build.h>
  12. #include <openssl/core_names.h>
  13. #include <openssl/evp.h>
  14. #include "testutil.h"
  15. #include "fake_cipherprov.h"
  16. static OSSL_LIB_CTX *libctx = NULL;
  17. static OSSL_PROVIDER *deflprov = NULL;
  18. #define KEY_SIZE 16
  19. static OSSL_CALLBACK ossl_pkey_todata_cb;
  20. static int ossl_pkey_todata_cb(const OSSL_PARAM params[], void *arg)
  21. {
  22. OSSL_PARAM **ret = arg;
  23. *ret = OSSL_PARAM_dup(params);
  24. return 1;
  25. }
  26. static int test_skey_cipher(void)
  27. {
  28. int ret = 0;
  29. OSSL_PROVIDER *fake_prov = NULL;
  30. EVP_SKEY *key = NULL;
  31. EVP_CIPHER *fake_cipher = NULL;
  32. EVP_CIPHER_CTX *ctx = NULL;
  33. const unsigned char import_key[KEY_SIZE] = {
  34. 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59,
  35. 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59,
  36. };
  37. OSSL_PARAM params[3];
  38. OSSL_PARAM *export_params = NULL;
  39. const unsigned char *export;
  40. size_t export_len;
  41. if (!TEST_ptr(fake_prov = fake_cipher_start(libctx)))
  42. return 0;
  43. /* Do a direct fetch to see it works */
  44. fake_cipher = EVP_CIPHER_fetch(libctx, "fake_cipher", FAKE_CIPHER_FETCH_PROPS);
  45. if (!TEST_ptr(fake_cipher))
  46. goto end;
  47. /* Create EVP_SKEY */
  48. params[0] = OSSL_PARAM_construct_utf8_string(FAKE_CIPHER_PARAM_KEY_NAME,
  49. "fake key name", 0);
  50. params[1] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES,
  51. (void *)import_key, KEY_SIZE);
  52. params[2] = OSSL_PARAM_construct_end();
  53. key = EVP_SKEY_import(libctx, "fake_cipher", FAKE_CIPHER_FETCH_PROPS,
  54. OSSL_SKEYMGMT_SELECT_ALL, params);
  55. if (!TEST_ptr(key))
  56. goto end;
  57. /* Init cipher */
  58. if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
  59. || !TEST_int_gt(EVP_CipherInit_SKEY(ctx, fake_cipher, key, NULL, 0, 1, NULL), 0))
  60. goto end;
  61. /* Export params */
  62. if (!TEST_int_gt(EVP_SKEY_export(key, OSSL_SKEYMGMT_SELECT_SECRET_KEY,
  63. ossl_pkey_todata_cb, &export_params), 0))
  64. goto end;
  65. /* Export raw key */
  66. if (!TEST_int_gt(EVP_SKEY_get0_raw_key(key, &export, &export_len), 0)
  67. || !TEST_mem_eq(export, export_len, import_key, sizeof(import_key)))
  68. goto end;
  69. ret = 1;
  70. end:
  71. OSSL_PARAM_free(export_params);
  72. EVP_SKEY_free(key);
  73. EVP_CIPHER_free(fake_cipher);
  74. EVP_CIPHER_CTX_free(ctx);
  75. fake_cipher_finish(fake_prov);
  76. return ret;
  77. }
  78. #define IV_SIZE 16
  79. #define DATA_SIZE 32
  80. static int test_aes_raw_skey(void)
  81. {
  82. const unsigned char data[DATA_SIZE] = {
  83. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
  84. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
  85. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
  86. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2
  87. };
  88. unsigned char aes_key[KEY_SIZE], aes_iv[IV_SIZE];
  89. unsigned char encrypted_skey[DATA_SIZE + IV_SIZE];
  90. unsigned char encrypted_raw[DATA_SIZE + IV_SIZE];
  91. int enc_len, fin_len;
  92. const unsigned char *export_key = NULL;
  93. size_t export_length;
  94. EVP_CIPHER *aes_cbc = NULL;
  95. EVP_CIPHER_CTX *ctx = NULL;
  96. EVP_SKEY *skey = NULL;
  97. OSSL_PARAM_BLD *tmpl = NULL;
  98. OSSL_PARAM *params = NULL;
  99. int ret = 0;
  100. deflprov = OSSL_PROVIDER_load(libctx, "default");
  101. if (!TEST_ptr(deflprov))
  102. return 0;
  103. memset(encrypted_skey, 0, sizeof(encrypted_skey));
  104. memset(encrypted_raw, 0, sizeof(encrypted_raw));
  105. memset(aes_key, 1, KEY_SIZE);
  106. memset(aes_iv, 2, IV_SIZE);
  107. /* Do a direct fetch to see it works */
  108. aes_cbc = EVP_CIPHER_fetch(libctx, "AES-128-CBC", "provider=default");
  109. if (!TEST_ptr(aes_cbc))
  110. goto end;
  111. /* Create EVP_SKEY */
  112. skey = EVP_SKEY_import_raw_key(libctx, "AES-128", aes_key, KEY_SIZE, NULL);
  113. if (!TEST_ptr(skey))
  114. goto end;
  115. if (!TEST_int_gt(EVP_SKEY_get0_raw_key(skey, &export_key, &export_length), 0)
  116. || !TEST_mem_eq(aes_key, KEY_SIZE, export_key, export_length))
  117. goto end;
  118. enc_len = sizeof(encrypted_skey);
  119. fin_len = 0;
  120. if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
  121. || !TEST_int_gt(EVP_CipherInit_SKEY(ctx, aes_cbc, skey, aes_iv, IV_SIZE, 1, NULL), 0)
  122. || !TEST_int_gt(EVP_CipherUpdate(ctx, encrypted_skey, &enc_len, data, DATA_SIZE), 0)
  123. || !TEST_int_gt(EVP_CipherFinal(ctx, encrypted_skey + enc_len, &fin_len), 0))
  124. goto end;
  125. EVP_CIPHER_CTX_free(ctx);
  126. ctx = EVP_CIPHER_CTX_new();
  127. enc_len = sizeof(encrypted_raw);
  128. fin_len = 0;
  129. if (!TEST_int_gt(EVP_CipherInit_ex2(ctx, aes_cbc, aes_key, aes_iv, 1, NULL), 0)
  130. || !TEST_int_gt(EVP_CipherUpdate(ctx, encrypted_raw, &enc_len, data, DATA_SIZE), 0)
  131. || !TEST_int_gt(EVP_CipherFinal(ctx, encrypted_raw + enc_len, &fin_len), 0)
  132. || !TEST_mem_eq(encrypted_skey, DATA_SIZE + IV_SIZE, encrypted_raw, DATA_SIZE + IV_SIZE))
  133. goto end;
  134. ret = 1;
  135. end:
  136. OSSL_PARAM_free(params);
  137. OSSL_PARAM_BLD_free(tmpl);
  138. EVP_SKEY_free(skey);
  139. EVP_CIPHER_free(aes_cbc);
  140. EVP_CIPHER_CTX_free(ctx);
  141. OSSL_PROVIDER_unload(deflprov);
  142. return ret;
  143. }
  144. #ifndef OPENSSL_NO_DES
  145. /* DES is used to test a "skey-unware" cipher provider */
  146. # define DES_KEY_SIZE 24
  147. # define DES_IV_SIZE 8
  148. static int test_des_raw_skey(void)
  149. {
  150. const unsigned char data[DATA_SIZE] = {
  151. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
  152. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
  153. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
  154. 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2
  155. };
  156. unsigned char des_key[DES_KEY_SIZE], des_iv[DES_IV_SIZE];
  157. unsigned char encrypted_skey[DATA_SIZE + DES_IV_SIZE];
  158. unsigned char encrypted_raw[DATA_SIZE + DES_IV_SIZE];
  159. int enc_len, fin_len;
  160. const unsigned char *export_key = NULL;
  161. size_t export_length;
  162. EVP_CIPHER *des_cbc = NULL;
  163. EVP_CIPHER_CTX *ctx = NULL;
  164. EVP_SKEY *skey = NULL;
  165. int ret = 0;
  166. deflprov = OSSL_PROVIDER_load(libctx, "default");
  167. if (!TEST_ptr(deflprov))
  168. return 0;
  169. memset(encrypted_skey, 0, sizeof(encrypted_skey));
  170. memset(encrypted_raw, 0, sizeof(encrypted_raw));
  171. memset(des_key, 1, DES_KEY_SIZE);
  172. memset(des_iv, 2, DES_IV_SIZE);
  173. /* Do a direct fetch to see it works */
  174. des_cbc = EVP_CIPHER_fetch(libctx, "DES-EDE3-CBC", "provider=default");
  175. if (!TEST_ptr(des_cbc))
  176. goto end;
  177. /* Create EVP_SKEY */
  178. skey = EVP_SKEY_import_raw_key(libctx, "DES", des_key, sizeof(des_key),
  179. NULL);
  180. if (!TEST_ptr(skey))
  181. goto end;
  182. if (!TEST_int_gt(EVP_SKEY_get0_raw_key(skey, &export_key, &export_length), 0)
  183. || !TEST_mem_eq(des_key, DES_KEY_SIZE, export_key, export_length))
  184. goto end;
  185. enc_len = sizeof(encrypted_skey);
  186. fin_len = 0;
  187. if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
  188. || !TEST_int_gt(EVP_CipherInit_SKEY(ctx, des_cbc, skey, des_iv, DES_IV_SIZE, 1, NULL), 0)
  189. || !TEST_int_gt(EVP_CipherUpdate(ctx, encrypted_skey, &enc_len, data, DATA_SIZE), 0)
  190. || !TEST_int_gt(EVP_CipherFinal(ctx, encrypted_skey + enc_len, &fin_len), 0))
  191. goto end;
  192. EVP_CIPHER_CTX_free(ctx);
  193. ctx = EVP_CIPHER_CTX_new();
  194. enc_len = sizeof(encrypted_raw);
  195. fin_len = 0;
  196. if (!TEST_int_gt(EVP_CipherInit_ex2(ctx, des_cbc, des_key, des_iv, 1, NULL), 0)
  197. || !TEST_int_gt(EVP_CipherUpdate(ctx, encrypted_raw, &enc_len, data, DATA_SIZE), 0)
  198. || !TEST_int_gt(EVP_CipherFinal(ctx, encrypted_raw + enc_len, &fin_len), 0)
  199. || !TEST_mem_eq(encrypted_skey, DATA_SIZE + DES_IV_SIZE, encrypted_raw,
  200. DATA_SIZE + DES_IV_SIZE))
  201. goto end;
  202. ret = 1;
  203. end:
  204. EVP_SKEY_free(skey);
  205. EVP_CIPHER_free(des_cbc);
  206. EVP_CIPHER_CTX_free(ctx);
  207. OSSL_PROVIDER_unload(deflprov);
  208. return ret;
  209. }
  210. #endif
  211. int setup_tests(void)
  212. {
  213. libctx = OSSL_LIB_CTX_new();
  214. if (libctx == NULL)
  215. return 0;
  216. ADD_TEST(test_skey_cipher);
  217. ADD_TEST(test_aes_raw_skey);
  218. #ifndef OPENSSL_NO_DES
  219. ADD_TEST(test_des_raw_skey);
  220. #endif
  221. return 1;
  222. }
  223. void cleanup_tests(void)
  224. {
  225. OSSL_LIB_CTX_free(libctx);
  226. }