crypto_kx.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <stddef.h>
  2. #include "core.h"
  3. #include "crypto_generichash.h"
  4. #include "crypto_kx.h"
  5. #include "crypto_scalarmult.h"
  6. #include "private/common.h"
  7. #include "randombytes.h"
  8. #include "utils.h"
  9. int
  10. crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
  11. unsigned char sk[crypto_kx_SECRETKEYBYTES],
  12. const unsigned char seed[crypto_kx_SEEDBYTES])
  13. {
  14. crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
  15. seed, crypto_kx_SEEDBYTES, NULL, 0);
  16. return crypto_scalarmult_base(pk, sk);
  17. }
  18. int
  19. crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
  20. unsigned char sk[crypto_kx_SECRETKEYBYTES])
  21. {
  22. COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES);
  23. COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES);
  24. randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
  25. return crypto_scalarmult_base(pk, sk);
  26. }
  27. int
  28. crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
  29. unsigned char tx[crypto_kx_SESSIONKEYBYTES],
  30. const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
  31. const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
  32. const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
  33. {
  34. crypto_generichash_state h;
  35. unsigned char q[crypto_scalarmult_BYTES];
  36. unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
  37. int i;
  38. if (rx == NULL) {
  39. rx = tx;
  40. }
  41. if (tx == NULL) {
  42. tx = rx;
  43. }
  44. if (rx == NULL) {
  45. sodium_misuse(); /* LCOV_EXCL_LINE */
  46. }
  47. if (crypto_scalarmult(q, client_sk, server_pk) != 0) {
  48. return -1;
  49. }
  50. COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
  51. crypto_generichash_init(&h, NULL, 0U, sizeof keys);
  52. crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
  53. sodium_memzero(q, sizeof q);
  54. crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
  55. crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
  56. crypto_generichash_final(&h, keys, sizeof keys);
  57. sodium_memzero(&h, sizeof h);
  58. for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
  59. rx[i] = keys[i]; /* rx cannot be NULL */
  60. tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; /* tx cannot be NULL */
  61. }
  62. sodium_memzero(keys, sizeof keys);
  63. return 0;
  64. }
  65. int
  66. crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
  67. unsigned char tx[crypto_kx_SESSIONKEYBYTES],
  68. const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
  69. const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
  70. const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])
  71. {
  72. crypto_generichash_state h;
  73. unsigned char q[crypto_scalarmult_BYTES];
  74. unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
  75. int i;
  76. if (rx == NULL) {
  77. rx = tx;
  78. }
  79. if (tx == NULL) {
  80. tx = rx;
  81. }
  82. if (rx == NULL) {
  83. sodium_misuse(); /* LCOV_EXCL_LINE */
  84. }
  85. if (crypto_scalarmult(q, server_sk, client_pk) != 0) {
  86. return -1;
  87. }
  88. COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
  89. crypto_generichash_init(&h, NULL, 0U, sizeof keys);
  90. crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
  91. sodium_memzero(q, sizeof q);
  92. crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
  93. crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
  94. crypto_generichash_final(&h, keys, sizeof keys);
  95. sodium_memzero(&h, sizeof h);
  96. for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
  97. tx[i] = keys[i];
  98. rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
  99. }
  100. sodium_memzero(keys, sizeof keys);
  101. return 0;
  102. }
  103. size_t
  104. crypto_kx_publickeybytes(void)
  105. {
  106. return crypto_kx_PUBLICKEYBYTES;
  107. }
  108. size_t
  109. crypto_kx_secretkeybytes(void)
  110. {
  111. return crypto_kx_SECRETKEYBYTES;
  112. }
  113. size_t
  114. crypto_kx_seedbytes(void)
  115. {
  116. return crypto_kx_SEEDBYTES;
  117. }
  118. size_t
  119. crypto_kx_sessionkeybytes(void)
  120. {
  121. return crypto_kx_SESSIONKEYBYTES;
  122. }
  123. const char *
  124. crypto_kx_primitive(void)
  125. {
  126. return crypto_kx_PRIMITIVE;
  127. }