signature.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Signature verification with an asymmetric key
  3. *
  4. * See Documentation/crypto/asymmetric-keys.rst
  5. *
  6. * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
  7. * Written by David Howells ([email protected])
  8. */
  9. #define pr_fmt(fmt) "SIG: "fmt
  10. #include <keys/asymmetric-subtype.h>
  11. #include <linux/export.h>
  12. #include <linux/err.h>
  13. #include <linux/slab.h>
  14. #include <linux/keyctl.h>
  15. #include <crypto/public_key.h>
  16. #include <keys/user-type.h>
  17. #include "asymmetric_keys.h"
  18. /*
  19. * Destroy a public key signature.
  20. */
  21. void public_key_signature_free(struct public_key_signature *sig)
  22. {
  23. int i;
  24. if (sig) {
  25. for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)
  26. kfree(sig->auth_ids[i]);
  27. kfree(sig->s);
  28. kfree(sig->digest);
  29. kfree(sig);
  30. }
  31. }
  32. EXPORT_SYMBOL_GPL(public_key_signature_free);
  33. /**
  34. * query_asymmetric_key - Get information about an asymmetric key.
  35. * @params: Various parameters.
  36. * @info: Where to put the information.
  37. */
  38. int query_asymmetric_key(const struct kernel_pkey_params *params,
  39. struct kernel_pkey_query *info)
  40. {
  41. const struct asymmetric_key_subtype *subtype;
  42. struct key *key = params->key;
  43. int ret;
  44. pr_devel("==>%s()\n", __func__);
  45. if (key->type != &key_type_asymmetric)
  46. return -EINVAL;
  47. subtype = asymmetric_key_subtype(key);
  48. if (!subtype ||
  49. !key->payload.data[0])
  50. return -EINVAL;
  51. if (!subtype->query)
  52. return -ENOTSUPP;
  53. ret = subtype->query(params, info);
  54. pr_devel("<==%s() = %d\n", __func__, ret);
  55. return ret;
  56. }
  57. EXPORT_SYMBOL_GPL(query_asymmetric_key);
  58. /**
  59. * encrypt_blob - Encrypt data using an asymmetric key
  60. * @params: Various parameters
  61. * @data: Data blob to be encrypted, length params->data_len
  62. * @enc: Encrypted data buffer, length params->enc_len
  63. *
  64. * Encrypt the specified data blob using the private key specified by
  65. * params->key. The encrypted data is wrapped in an encoding if
  66. * params->encoding is specified (eg. "pkcs1").
  67. *
  68. * Returns the length of the data placed in the encrypted data buffer or an
  69. * error.
  70. */
  71. int encrypt_blob(struct kernel_pkey_params *params,
  72. const void *data, void *enc)
  73. {
  74. params->op = kernel_pkey_encrypt;
  75. return asymmetric_key_eds_op(params, data, enc);
  76. }
  77. EXPORT_SYMBOL_GPL(encrypt_blob);
  78. /**
  79. * decrypt_blob - Decrypt data using an asymmetric key
  80. * @params: Various parameters
  81. * @enc: Encrypted data to be decrypted, length params->enc_len
  82. * @data: Decrypted data buffer, length params->data_len
  83. *
  84. * Decrypt the specified data blob using the private key specified by
  85. * params->key. The decrypted data is wrapped in an encoding if
  86. * params->encoding is specified (eg. "pkcs1").
  87. *
  88. * Returns the length of the data placed in the decrypted data buffer or an
  89. * error.
  90. */
  91. int decrypt_blob(struct kernel_pkey_params *params,
  92. const void *enc, void *data)
  93. {
  94. params->op = kernel_pkey_decrypt;
  95. return asymmetric_key_eds_op(params, enc, data);
  96. }
  97. EXPORT_SYMBOL_GPL(decrypt_blob);
  98. /**
  99. * create_signature - Sign some data using an asymmetric key
  100. * @params: Various parameters
  101. * @data: Data blob to be signed, length params->data_len
  102. * @enc: Signature buffer, length params->enc_len
  103. *
  104. * Sign the specified data blob using the private key specified by params->key.
  105. * The signature is wrapped in an encoding if params->encoding is specified
  106. * (eg. "pkcs1"). If the encoding needs to know the digest type, this can be
  107. * passed through params->hash_algo (eg. "sha1").
  108. *
  109. * Returns the length of the data placed in the signature buffer or an error.
  110. */
  111. int create_signature(struct kernel_pkey_params *params,
  112. const void *data, void *enc)
  113. {
  114. params->op = kernel_pkey_sign;
  115. return asymmetric_key_eds_op(params, data, enc);
  116. }
  117. EXPORT_SYMBOL_GPL(create_signature);
  118. /**
  119. * verify_signature - Initiate the use of an asymmetric key to verify a signature
  120. * @key: The asymmetric key to verify against
  121. * @sig: The signature to check
  122. *
  123. * Returns 0 if successful or else an error.
  124. */
  125. int verify_signature(const struct key *key,
  126. const struct public_key_signature *sig)
  127. {
  128. const struct asymmetric_key_subtype *subtype;
  129. int ret;
  130. pr_devel("==>%s()\n", __func__);
  131. if (key->type != &key_type_asymmetric)
  132. return -EINVAL;
  133. subtype = asymmetric_key_subtype(key);
  134. if (!subtype ||
  135. !key->payload.data[0])
  136. return -EINVAL;
  137. if (!subtype->verify_signature)
  138. return -ENOTSUPP;
  139. ret = subtype->verify_signature(key, sig);
  140. pr_devel("<==%s() = %d\n", __func__, ret);
  141. return ret;
  142. }
  143. EXPORT_SYMBOL_GPL(verify_signature);