uecc.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to
  6. * deal in the Software without restriction, including without limitation the
  7. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. * sell copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. * IN THE SOFTWARE.
  21. */
  22. #include <fcntl.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #ifdef _WINDOWS
  27. #include "wincompat.h"
  28. #else
  29. #include <unistd.h>
  30. #endif
  31. #include "sha2.h"
  32. #include "uECC.h"
  33. #include "uECC_vli.h"
  34. #include "picotls.h"
  35. #include "picotls/minicrypto.h"
  36. #define TYPE_UNCOMPRESSED_PUBLIC_KEY 4
  37. struct st_secp256r1_key_exhchange_t {
  38. ptls_key_exchange_context_t super;
  39. uint8_t priv[SECP256R1_PRIVATE_KEY_SIZE];
  40. uint8_t pub[SECP256R1_PUBLIC_KEY_SIZE];
  41. };
  42. static int secp256r1_on_exchange(ptls_key_exchange_context_t **_ctx, int release, ptls_iovec_t *secret, ptls_iovec_t peerkey)
  43. {
  44. struct st_secp256r1_key_exhchange_t *ctx = (struct st_secp256r1_key_exhchange_t *)*_ctx;
  45. uint8_t *secbytes = NULL;
  46. int ret;
  47. if (secret == NULL) {
  48. ret = 0;
  49. goto Exit;
  50. }
  51. if (peerkey.len != SECP256R1_PUBLIC_KEY_SIZE || peerkey.base[0] != TYPE_UNCOMPRESSED_PUBLIC_KEY) {
  52. ret = PTLS_ALERT_DECRYPT_ERROR;
  53. goto Exit;
  54. }
  55. if ((secbytes = (uint8_t *)malloc(SECP256R1_SHARED_SECRET_SIZE)) == NULL) {
  56. ret = PTLS_ERROR_NO_MEMORY;
  57. goto Exit;
  58. }
  59. if (!uECC_shared_secret(peerkey.base + 1, ctx->priv, secbytes, uECC_secp256r1())) {
  60. ret = PTLS_ALERT_DECRYPT_ERROR;
  61. goto Exit;
  62. }
  63. *secret = ptls_iovec_init(secbytes, SECP256R1_SHARED_SECRET_SIZE);
  64. ret = 0;
  65. Exit:
  66. if (ret != 0)
  67. free(secbytes);
  68. if (release) {
  69. ptls_clear_memory(ctx->priv, sizeof(ctx->priv));
  70. free(ctx);
  71. *_ctx = NULL;
  72. }
  73. return ret;
  74. }
  75. static int secp256r1_create_key_exchange(ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **_ctx)
  76. {
  77. struct st_secp256r1_key_exhchange_t *ctx;
  78. if ((ctx = (struct st_secp256r1_key_exhchange_t *)malloc(sizeof(*ctx))) == NULL)
  79. return PTLS_ERROR_NO_MEMORY;
  80. ctx->super = (ptls_key_exchange_context_t){algo, ptls_iovec_init(ctx->pub, sizeof(ctx->pub)), secp256r1_on_exchange};
  81. ctx->pub[0] = TYPE_UNCOMPRESSED_PUBLIC_KEY;
  82. /* RNG function must be set before calling uECC_make_key() */
  83. assert(uECC_get_rng() != NULL);
  84. uECC_make_key(ctx->pub + 1, ctx->priv, uECC_secp256r1());
  85. *_ctx = &ctx->super;
  86. return 0;
  87. }
  88. static int secp256r1_key_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret,
  89. ptls_iovec_t peerkey)
  90. {
  91. uint8_t priv[SECP256R1_PRIVATE_KEY_SIZE], *pub = NULL, *secbytes = NULL;
  92. int ret;
  93. if (peerkey.len != SECP256R1_PUBLIC_KEY_SIZE || peerkey.base[0] != TYPE_UNCOMPRESSED_PUBLIC_KEY) {
  94. ret = PTLS_ALERT_DECRYPT_ERROR;
  95. goto Exit;
  96. }
  97. if ((pub = malloc(SECP256R1_PUBLIC_KEY_SIZE)) == NULL) {
  98. ret = PTLS_ERROR_NO_MEMORY;
  99. goto Exit;
  100. }
  101. if ((secbytes = malloc(SECP256R1_SHARED_SECRET_SIZE)) == NULL) {
  102. ret = PTLS_ERROR_NO_MEMORY;
  103. goto Exit;
  104. }
  105. pub[0] = TYPE_UNCOMPRESSED_PUBLIC_KEY;
  106. uECC_make_key(pub + 1, priv, uECC_secp256r1());
  107. if (!uECC_shared_secret(peerkey.base + 1, priv, secbytes, uECC_secp256r1())) {
  108. ret = PTLS_ALERT_DECRYPT_ERROR;
  109. goto Exit;
  110. }
  111. *pubkey = ptls_iovec_init(pub, SECP256R1_PUBLIC_KEY_SIZE);
  112. *secret = ptls_iovec_init(secbytes, SECP256R1_SHARED_SECRET_SIZE);
  113. ret = 0;
  114. Exit:
  115. ptls_clear_memory(priv, sizeof(priv));
  116. if (ret != 0) {
  117. free(secbytes);
  118. free(pub);
  119. }
  120. return ret;
  121. }
  122. static int secp256r1sha256_sign(ptls_sign_certificate_t *_self, ptls_t *tls, ptls_async_job_t **async, uint16_t *selected_algorithm,
  123. ptls_buffer_t *outbuf, ptls_iovec_t input, const uint16_t *algorithms, size_t num_algorithms)
  124. {
  125. ptls_minicrypto_secp256r1sha256_sign_certificate_t *self = (ptls_minicrypto_secp256r1sha256_sign_certificate_t *)_self;
  126. uint8_t hash[32], sig[64];
  127. size_t i;
  128. int ret;
  129. /* check algorithm */
  130. for (i = 0; i != num_algorithms; ++i)
  131. if (algorithms[i] == PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256)
  132. break;
  133. if (i == num_algorithms)
  134. return PTLS_ALERT_HANDSHAKE_FAILURE;
  135. { /* calc hash */
  136. cf_sha256_context ctx;
  137. cf_sha256_init(&ctx);
  138. cf_sha256_update(&ctx, input.base, input.len);
  139. cf_sha256_digest_final(&ctx, hash);
  140. ptls_clear_memory(&ctx, sizeof(ctx));
  141. }
  142. /* sign */
  143. uECC_sign(self->key, hash, sizeof(hash), sig, uECC_secp256r1());
  144. /* encode using DER */
  145. ptls_buffer_push_asn1_sequence(outbuf, {
  146. if ((ret = ptls_buffer_push_asn1_ubigint(outbuf, sig, 32)) != 0)
  147. goto Exit;
  148. if ((ret = ptls_buffer_push_asn1_ubigint(outbuf, sig + 32, 32)) != 0)
  149. goto Exit;
  150. });
  151. *selected_algorithm = PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256;
  152. ret = 0;
  153. Exit:
  154. ptls_clear_memory(hash, sizeof(hash));
  155. ptls_clear_memory(sig, sizeof(sig));
  156. return ret;
  157. }
  158. int ptls_minicrypto_init_secp256r1sha256_sign_certificate(ptls_minicrypto_secp256r1sha256_sign_certificate_t *self,
  159. ptls_iovec_t key)
  160. {
  161. if (key.len != sizeof(self->key))
  162. return PTLS_ERROR_INCOMPATIBLE_KEY;
  163. self->super.cb = secp256r1sha256_sign;
  164. memcpy(self->key, key.base, sizeof(self->key));
  165. return 0;
  166. }
  167. ptls_key_exchange_algorithm_t ptls_minicrypto_secp256r1 = {.id = PTLS_GROUP_SECP256R1,
  168. .name = PTLS_GROUP_NAME_SECP256R1,
  169. .create = secp256r1_create_key_exchange,
  170. .exchange = secp256r1_key_exchange};
  171. ptls_key_exchange_algorithm_t *ptls_minicrypto_key_exchanges[] = {&ptls_minicrypto_secp256r1, NULL};