p_x25519.c.grpc_back 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* Copyright (c) 2019, Google Inc.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. #include <openssl_grpc/evp.h>
  15. #include <openssl_grpc/curve25519.h>
  16. #include <openssl_grpc/err.h>
  17. #include <openssl_grpc/mem.h>
  18. #include "internal.h"
  19. // X25519 has no parameters to copy.
  20. static int pkey_x25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; }
  21. static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
  22. X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY));
  23. if (key == NULL) {
  24. OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
  25. return 0;
  26. }
  27. if (!EVP_PKEY_set_type(pkey, EVP_PKEY_X25519)) {
  28. OPENSSL_free(key);
  29. return 0;
  30. }
  31. X25519_keypair(key->pub, key->priv);
  32. key->has_private = 1;
  33. OPENSSL_free(pkey->pkey.ptr);
  34. pkey->pkey.ptr = key;
  35. return 1;
  36. }
  37. static int pkey_x25519_derive(EVP_PKEY_CTX *ctx, uint8_t *out,
  38. size_t *out_len) {
  39. if (ctx->pkey == NULL || ctx->peerkey == NULL) {
  40. OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
  41. return 0;
  42. }
  43. const X25519_KEY *our_key = ctx->pkey->pkey.ptr;
  44. const X25519_KEY *peer_key = ctx->peerkey->pkey.ptr;
  45. if (our_key == NULL || peer_key == NULL) {
  46. OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
  47. return 0;
  48. }
  49. if (!our_key->has_private) {
  50. OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY);
  51. return 0;
  52. }
  53. if (out != NULL) {
  54. if (*out_len < 32) {
  55. OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
  56. return 0;
  57. }
  58. if (!X25519(out, our_key->priv, peer_key->pub)) {
  59. OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
  60. return 0;
  61. }
  62. }
  63. *out_len = 32;
  64. return 1;
  65. }
  66. static int pkey_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
  67. switch (type) {
  68. case EVP_PKEY_CTRL_PEER_KEY:
  69. // |EVP_PKEY_derive_set_peer| requires the key implement this command,
  70. // even if it is a no-op.
  71. return 1;
  72. default:
  73. OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  74. return 0;
  75. }
  76. }
  77. const EVP_PKEY_METHOD x25519_pkey_meth = {
  78. EVP_PKEY_X25519,
  79. NULL /* init */,
  80. pkey_x25519_copy,
  81. NULL /* cleanup */,
  82. pkey_x25519_keygen,
  83. NULL /* sign */,
  84. NULL /* sign_message */,
  85. NULL /* verify */,
  86. NULL /* verify_message */,
  87. NULL /* verify_recover */,
  88. NULL /* encrypt */,
  89. NULL /* decrypt */,
  90. pkey_x25519_derive,
  91. NULL /* paramgen */,
  92. pkey_x25519_ctrl,
  93. };