ssl_key_share.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /* Copyright (c) 2015, 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/ssl.h>
  15. #include <assert.h>
  16. #include <string.h>
  17. #include <utility>
  18. #include <openssl/bn.h>
  19. #include <openssl/bytestring.h>
  20. #include <openssl/curve25519.h>
  21. #include <openssl/ec.h>
  22. #include <openssl/err.h>
  23. #include <openssl/hrss.h>
  24. #include <openssl/mem.h>
  25. #include <openssl/nid.h>
  26. #include <openssl/rand.h>
  27. #include "internal.h"
  28. #include "../crypto/internal.h"
  29. #include "../third_party/sike/sike.h"
  30. BSSL_NAMESPACE_BEGIN
  31. namespace {
  32. class ECKeyShare : public SSLKeyShare {
  33. public:
  34. ECKeyShare(int nid, uint16_t group_id) : nid_(nid), group_id_(group_id) {}
  35. uint16_t GroupID() const override { return group_id_; }
  36. bool Offer(CBB *out) override {
  37. assert(!private_key_);
  38. // Set up a shared |BN_CTX| for all operations.
  39. UniquePtr<BN_CTX> bn_ctx(BN_CTX_new());
  40. if (!bn_ctx) {
  41. return false;
  42. }
  43. BN_CTXScope scope(bn_ctx.get());
  44. // Generate a private key.
  45. UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(nid_));
  46. private_key_.reset(BN_new());
  47. if (!group || !private_key_ ||
  48. !BN_rand_range_ex(private_key_.get(), 1,
  49. EC_GROUP_get0_order(group.get()))) {
  50. return false;
  51. }
  52. // Compute the corresponding public key and serialize it.
  53. UniquePtr<EC_POINT> public_key(EC_POINT_new(group.get()));
  54. if (!public_key ||
  55. !EC_POINT_mul(group.get(), public_key.get(), private_key_.get(), NULL,
  56. NULL, bn_ctx.get()) ||
  57. !EC_POINT_point2cbb(out, group.get(), public_key.get(),
  58. POINT_CONVERSION_UNCOMPRESSED, bn_ctx.get())) {
  59. return false;
  60. }
  61. return true;
  62. }
  63. bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
  64. Span<const uint8_t> peer_key) override {
  65. assert(private_key_);
  66. *out_alert = SSL_AD_INTERNAL_ERROR;
  67. // Set up a shared |BN_CTX| for all operations.
  68. UniquePtr<BN_CTX> bn_ctx(BN_CTX_new());
  69. if (!bn_ctx) {
  70. return false;
  71. }
  72. BN_CTXScope scope(bn_ctx.get());
  73. UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(nid_));
  74. if (!group) {
  75. return false;
  76. }
  77. UniquePtr<EC_POINT> peer_point(EC_POINT_new(group.get()));
  78. UniquePtr<EC_POINT> result(EC_POINT_new(group.get()));
  79. BIGNUM *x = BN_CTX_get(bn_ctx.get());
  80. if (!peer_point || !result || !x) {
  81. return false;
  82. }
  83. if (peer_key.empty() || peer_key[0] != POINT_CONVERSION_UNCOMPRESSED ||
  84. !EC_POINT_oct2point(group.get(), peer_point.get(), peer_key.data(),
  85. peer_key.size(), bn_ctx.get())) {
  86. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
  87. *out_alert = SSL_AD_DECODE_ERROR;
  88. return false;
  89. }
  90. // Compute the x-coordinate of |peer_key| * |private_key_|.
  91. if (!EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(),
  92. private_key_.get(), bn_ctx.get()) ||
  93. !EC_POINT_get_affine_coordinates_GFp(group.get(), result.get(), x, NULL,
  94. bn_ctx.get())) {
  95. return false;
  96. }
  97. // Encode the x-coordinate left-padded with zeros.
  98. Array<uint8_t> secret;
  99. if (!secret.Init((EC_GROUP_get_degree(group.get()) + 7) / 8) ||
  100. !BN_bn2bin_padded(secret.data(), secret.size(), x)) {
  101. return false;
  102. }
  103. *out_secret = std::move(secret);
  104. return true;
  105. }
  106. bool Serialize(CBB *out) override {
  107. assert(private_key_);
  108. CBB cbb;
  109. UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(nid_));
  110. // Padding is added to avoid leaking the length.
  111. size_t len = BN_num_bytes(EC_GROUP_get0_order(group.get()));
  112. if (!CBB_add_asn1_uint64(out, group_id_) ||
  113. !CBB_add_asn1(out, &cbb, CBS_ASN1_OCTETSTRING) ||
  114. !BN_bn2cbb_padded(&cbb, len, private_key_.get()) ||
  115. !CBB_flush(out)) {
  116. return false;
  117. }
  118. return true;
  119. }
  120. bool Deserialize(CBS *in) override {
  121. assert(!private_key_);
  122. CBS private_key;
  123. if (!CBS_get_asn1(in, &private_key, CBS_ASN1_OCTETSTRING)) {
  124. return false;
  125. }
  126. private_key_.reset(BN_bin2bn(CBS_data(&private_key),
  127. CBS_len(&private_key), nullptr));
  128. return private_key_ != nullptr;
  129. }
  130. private:
  131. UniquePtr<BIGNUM> private_key_;
  132. int nid_;
  133. uint16_t group_id_;
  134. };
  135. class X25519KeyShare : public SSLKeyShare {
  136. public:
  137. X25519KeyShare() {}
  138. uint16_t GroupID() const override { return SSL_CURVE_X25519; }
  139. bool Offer(CBB *out) override {
  140. uint8_t public_key[32];
  141. X25519_keypair(public_key, private_key_);
  142. return !!CBB_add_bytes(out, public_key, sizeof(public_key));
  143. }
  144. bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
  145. Span<const uint8_t> peer_key) override {
  146. *out_alert = SSL_AD_INTERNAL_ERROR;
  147. Array<uint8_t> secret;
  148. if (!secret.Init(32)) {
  149. OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
  150. return false;
  151. }
  152. if (peer_key.size() != 32 ||
  153. !X25519(secret.data(), private_key_, peer_key.data())) {
  154. *out_alert = SSL_AD_DECODE_ERROR;
  155. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
  156. return false;
  157. }
  158. *out_secret = std::move(secret);
  159. return true;
  160. }
  161. bool Serialize(CBB *out) override {
  162. return (CBB_add_asn1_uint64(out, GroupID()) &&
  163. CBB_add_asn1_octet_string(out, private_key_, sizeof(private_key_)));
  164. }
  165. bool Deserialize(CBS *in) override {
  166. CBS key;
  167. if (!CBS_get_asn1(in, &key, CBS_ASN1_OCTETSTRING) ||
  168. CBS_len(&key) != sizeof(private_key_) ||
  169. !CBS_copy_bytes(&key, private_key_, sizeof(private_key_))) {
  170. return false;
  171. }
  172. return true;
  173. }
  174. private:
  175. uint8_t private_key_[32];
  176. };
  177. class CECPQ2KeyShare : public SSLKeyShare {
  178. public:
  179. CECPQ2KeyShare() {}
  180. uint16_t GroupID() const override { return SSL_CURVE_CECPQ2; }
  181. bool Offer(CBB *out) override {
  182. uint8_t x25519_public_key[32];
  183. X25519_keypair(x25519_public_key, x25519_private_key_);
  184. uint8_t hrss_entropy[HRSS_GENERATE_KEY_BYTES];
  185. HRSS_public_key hrss_public_key;
  186. RAND_bytes(hrss_entropy, sizeof(hrss_entropy));
  187. HRSS_generate_key(&hrss_public_key, &hrss_private_key_, hrss_entropy);
  188. uint8_t hrss_public_key_bytes[HRSS_PUBLIC_KEY_BYTES];
  189. HRSS_marshal_public_key(hrss_public_key_bytes, &hrss_public_key);
  190. if (!CBB_add_bytes(out, x25519_public_key, sizeof(x25519_public_key)) ||
  191. !CBB_add_bytes(out, hrss_public_key_bytes,
  192. sizeof(hrss_public_key_bytes))) {
  193. return false;
  194. }
  195. return true;
  196. }
  197. bool Accept(CBB *out_public_key, Array<uint8_t> *out_secret,
  198. uint8_t *out_alert, Span<const uint8_t> peer_key) override {
  199. Array<uint8_t> secret;
  200. if (!secret.Init(32 + HRSS_KEY_BYTES)) {
  201. OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
  202. return false;
  203. }
  204. uint8_t x25519_public_key[32];
  205. X25519_keypair(x25519_public_key, x25519_private_key_);
  206. HRSS_public_key peer_public_key;
  207. if (peer_key.size() != 32 + HRSS_PUBLIC_KEY_BYTES ||
  208. !HRSS_parse_public_key(&peer_public_key, peer_key.data() + 32) ||
  209. !X25519(secret.data(), x25519_private_key_, peer_key.data())) {
  210. *out_alert = SSL_AD_DECODE_ERROR;
  211. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
  212. return false;
  213. }
  214. uint8_t ciphertext[HRSS_CIPHERTEXT_BYTES];
  215. uint8_t entropy[HRSS_ENCAP_BYTES];
  216. RAND_bytes(entropy, sizeof(entropy));
  217. HRSS_encap(ciphertext, secret.data() + 32, &peer_public_key, entropy);
  218. if (!CBB_add_bytes(out_public_key, x25519_public_key,
  219. sizeof(x25519_public_key)) ||
  220. !CBB_add_bytes(out_public_key, ciphertext, sizeof(ciphertext))) {
  221. return false;
  222. }
  223. *out_secret = std::move(secret);
  224. return true;
  225. }
  226. bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
  227. Span<const uint8_t> peer_key) override {
  228. *out_alert = SSL_AD_INTERNAL_ERROR;
  229. Array<uint8_t> secret;
  230. if (!secret.Init(32 + HRSS_KEY_BYTES)) {
  231. OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
  232. return false;
  233. }
  234. if (peer_key.size() != 32 + HRSS_CIPHERTEXT_BYTES ||
  235. !X25519(secret.data(), x25519_private_key_, peer_key.data())) {
  236. *out_alert = SSL_AD_DECODE_ERROR;
  237. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
  238. return false;
  239. }
  240. HRSS_decap(secret.data() + 32, &hrss_private_key_, peer_key.data() + 32,
  241. peer_key.size() - 32);
  242. *out_secret = std::move(secret);
  243. return true;
  244. }
  245. private:
  246. uint8_t x25519_private_key_[32];
  247. HRSS_private_key hrss_private_key_;
  248. };
  249. class CECPQ2bKeyShare : public SSLKeyShare {
  250. public:
  251. uint16_t GroupID() const override { return SSL_CURVE_CECPQ2b; }
  252. bool Offer(CBB *out) override {
  253. uint8_t public_x25519[32] = {0};
  254. X25519_keypair(public_x25519, private_x25519_);
  255. if (!SIKE_keypair(private_sike_, public_sike_)) {
  256. return false;
  257. }
  258. return CBB_add_bytes(out, public_x25519, sizeof(public_x25519)) &&
  259. CBB_add_bytes(out, public_sike_, sizeof(public_sike_));
  260. }
  261. bool Accept(CBB *out_public_key, Array<uint8_t> *out_secret,
  262. uint8_t *out_alert, Span<const uint8_t> peer_key) override {
  263. uint8_t public_x25519[32];
  264. uint8_t private_x25519[32];
  265. uint8_t sike_ciphertext[SIKE_CT_BYTESZ] = {0};
  266. *out_alert = SSL_AD_INTERNAL_ERROR;
  267. if (peer_key.size() != sizeof(public_x25519) + SIKE_PUB_BYTESZ) {
  268. *out_alert = SSL_AD_DECODE_ERROR;
  269. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
  270. return false;
  271. }
  272. Array<uint8_t> secret;
  273. if (!secret.Init(sizeof(private_x25519_) + SIKE_SS_BYTESZ)) {
  274. OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
  275. return false;
  276. }
  277. X25519_keypair(public_x25519, private_x25519);
  278. if (!X25519(secret.data(), private_x25519, peer_key.data())) {
  279. *out_alert = SSL_AD_DECODE_ERROR;
  280. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
  281. return false;
  282. }
  283. SIKE_encaps(secret.data() + sizeof(private_x25519_), sike_ciphertext,
  284. peer_key.data() + sizeof(public_x25519));
  285. *out_secret = std::move(secret);
  286. return CBB_add_bytes(out_public_key, public_x25519,
  287. sizeof(public_x25519)) &&
  288. CBB_add_bytes(out_public_key, sike_ciphertext,
  289. sizeof(sike_ciphertext));
  290. }
  291. bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
  292. Span<const uint8_t> peer_key) override {
  293. *out_alert = SSL_AD_INTERNAL_ERROR;
  294. Array<uint8_t> secret;
  295. if (!secret.Init(sizeof(private_x25519_) + SIKE_SS_BYTESZ)) {
  296. OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
  297. return false;
  298. }
  299. if (peer_key.size() != 32 + SIKE_CT_BYTESZ ||
  300. !X25519(secret.data(), private_x25519_, peer_key.data())) {
  301. *out_alert = SSL_AD_DECODE_ERROR;
  302. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
  303. return false;
  304. }
  305. SIKE_decaps(secret.data() + sizeof(private_x25519_), peer_key.data() + 32,
  306. public_sike_, private_sike_);
  307. *out_secret = std::move(secret);
  308. return true;
  309. }
  310. private:
  311. uint8_t private_x25519_[32];
  312. uint8_t private_sike_[SIKE_PRV_BYTESZ];
  313. uint8_t public_sike_[SIKE_PUB_BYTESZ];
  314. };
  315. CONSTEXPR_ARRAY NamedGroup kNamedGroups[] = {
  316. {NID_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1"},
  317. {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1"},
  318. {NID_secp384r1, SSL_CURVE_SECP384R1, "P-384", "secp384r1"},
  319. {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1"},
  320. {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519"},
  321. {NID_CECPQ2, SSL_CURVE_CECPQ2, "CECPQ2", "CECPQ2"},
  322. {NID_CECPQ2b, SSL_CURVE_CECPQ2b, "CECPQ2b", "CECPQ2b"},
  323. };
  324. } // namespace
  325. Span<const NamedGroup> NamedGroups() {
  326. return MakeConstSpan(kNamedGroups, OPENSSL_ARRAY_SIZE(kNamedGroups));
  327. }
  328. UniquePtr<SSLKeyShare> SSLKeyShare::Create(uint16_t group_id) {
  329. switch (group_id) {
  330. case SSL_CURVE_SECP224R1:
  331. return UniquePtr<SSLKeyShare>(
  332. New<ECKeyShare>(NID_secp224r1, SSL_CURVE_SECP224R1));
  333. case SSL_CURVE_SECP256R1:
  334. return UniquePtr<SSLKeyShare>(
  335. New<ECKeyShare>(NID_X9_62_prime256v1, SSL_CURVE_SECP256R1));
  336. case SSL_CURVE_SECP384R1:
  337. return UniquePtr<SSLKeyShare>(
  338. New<ECKeyShare>(NID_secp384r1, SSL_CURVE_SECP384R1));
  339. case SSL_CURVE_SECP521R1:
  340. return UniquePtr<SSLKeyShare>(
  341. New<ECKeyShare>(NID_secp521r1, SSL_CURVE_SECP521R1));
  342. case SSL_CURVE_X25519:
  343. return UniquePtr<SSLKeyShare>(New<X25519KeyShare>());
  344. case SSL_CURVE_CECPQ2:
  345. return UniquePtr<SSLKeyShare>(New<CECPQ2KeyShare>());
  346. case SSL_CURVE_CECPQ2b:
  347. return UniquePtr<SSLKeyShare>(New<CECPQ2bKeyShare>());
  348. default:
  349. return nullptr;
  350. }
  351. }
  352. UniquePtr<SSLKeyShare> SSLKeyShare::Create(CBS *in) {
  353. uint64_t group;
  354. if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff) {
  355. return nullptr;
  356. }
  357. UniquePtr<SSLKeyShare> key_share = Create(static_cast<uint16_t>(group));
  358. if (!key_share || !key_share->Deserialize(in)) {
  359. return nullptr;
  360. }
  361. return key_share;
  362. }
  363. bool SSLKeyShare::Accept(CBB *out_public_key, Array<uint8_t> *out_secret,
  364. uint8_t *out_alert, Span<const uint8_t> peer_key) {
  365. *out_alert = SSL_AD_INTERNAL_ERROR;
  366. return Offer(out_public_key) &&
  367. Finish(out_secret, out_alert, peer_key);
  368. }
  369. bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid) {
  370. for (const auto &group : kNamedGroups) {
  371. if (group.nid == nid) {
  372. *out_group_id = group.group_id;
  373. return true;
  374. }
  375. }
  376. return false;
  377. }
  378. bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len) {
  379. for (const auto &group : kNamedGroups) {
  380. if (len == strlen(group.name) &&
  381. !strncmp(group.name, name, len)) {
  382. *out_group_id = group.group_id;
  383. return true;
  384. }
  385. if (len == strlen(group.alias) &&
  386. !strncmp(group.alias, name, len)) {
  387. *out_group_id = group.group_id;
  388. return true;
  389. }
  390. }
  391. return false;
  392. }
  393. BSSL_NAMESPACE_END
  394. using namespace bssl;
  395. const char* SSL_get_curve_name(uint16_t group_id) {
  396. for (const auto &group : kNamedGroups) {
  397. if (group.group_id == group_id) {
  398. return group.name;
  399. }
  400. }
  401. return nullptr;
  402. }