signature.c 4.6 KB

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