• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2020, 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 
15 #include <openssl/hpke.h>
16 
17 #include <cstdint>
18 #include <limits>
19 #include <string>
20 #include <vector>
21 
22 #include <gtest/gtest.h>
23 
24 #include <openssl/base.h>
25 #include <openssl/curve25519.h>
26 #include <openssl/digest.h>
27 #include <openssl/err.h>
28 #include <openssl/evp.h>
29 #include <openssl/rand.h>
30 #include <openssl/sha.h>
31 #include <openssl/span.h>
32 
33 #include "../test/file_test.h"
34 #include "../test/test_util.h"
35 
36 
37 namespace bssl {
38 namespace {
39 
40 const decltype(&EVP_hpke_aes_128_gcm) kAllAEADs[] = {
41     &EVP_hpke_aes_128_gcm,
42     &EVP_hpke_aes_256_gcm,
43     &EVP_hpke_chacha20_poly1305,
44 };
45 
46 const decltype(&EVP_hpke_hkdf_sha256) kAllKDFs[] = {
47     &EVP_hpke_hkdf_sha256,
48 };
49 
50 // HPKETestVector corresponds to one array member in the published
51 // test-vectors.json.
52 class HPKETestVector {
53  public:
54   explicit HPKETestVector() = default;
55   ~HPKETestVector() = default;
56 
57   bool ReadFromFileTest(FileTest *t);
58 
Verify() const59   void Verify() const {
60     const EVP_HPKE_KEM *kem = EVP_hpke_x25519_hkdf_sha256();
61     const EVP_HPKE_AEAD *aead = GetAEAD();
62     ASSERT_TRUE(aead);
63     const EVP_HPKE_KDF *kdf = GetKDF();
64     ASSERT_TRUE(kdf);
65 
66     // Test the sender.
67     ScopedEVP_HPKE_CTX sender_ctx;
68     uint8_t enc[EVP_HPKE_MAX_ENC_LENGTH];
69     size_t enc_len;
70     ASSERT_TRUE(EVP_HPKE_CTX_setup_sender_with_seed_for_testing(
71         sender_ctx.get(), enc, &enc_len, sizeof(enc), kem, kdf, aead,
72         public_key_r_.data(), public_key_r_.size(), info_.data(), info_.size(),
73         secret_key_e_.data(), secret_key_e_.size()));
74     EXPECT_EQ(Bytes(enc, enc_len), Bytes(public_key_e_));
75     VerifySender(sender_ctx.get());
76 
77     // Test the recipient.
78     ScopedEVP_HPKE_KEY base_key;
79     ASSERT_TRUE(EVP_HPKE_KEY_init(base_key.get(), kem, secret_key_r_.data(),
80                                   secret_key_r_.size()));
81     for (bool copy : {false, true}) {
82       SCOPED_TRACE(copy);
83       const EVP_HPKE_KEY *key = base_key.get();
84       ScopedEVP_HPKE_KEY key_copy;
85       if (copy) {
86         ASSERT_TRUE(EVP_HPKE_KEY_copy(key_copy.get(), base_key.get()));
87         key = key_copy.get();
88       }
89 
90       uint8_t public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
91       size_t public_key_len;
92       ASSERT_TRUE(EVP_HPKE_KEY_public_key(key, public_key, &public_key_len,
93                                           sizeof(public_key)));
94       EXPECT_EQ(Bytes(public_key, public_key_len), Bytes(public_key_r_));
95 
96       uint8_t private_key[EVP_HPKE_MAX_PRIVATE_KEY_LENGTH];
97       size_t private_key_len;
98       ASSERT_TRUE(EVP_HPKE_KEY_private_key(key, private_key, &private_key_len,
99                                            sizeof(private_key)));
100       EXPECT_EQ(Bytes(private_key, private_key_len), Bytes(secret_key_r_));
101 
102       // Set up the recipient.
103       ScopedEVP_HPKE_CTX recipient_ctx;
104       ASSERT_TRUE(EVP_HPKE_CTX_setup_recipient(recipient_ctx.get(), key, kdf,
105                                                aead, enc, enc_len, info_.data(),
106                                                info_.size()));
107 
108       VerifyRecipient(recipient_ctx.get());
109     }
110   }
111 
112  private:
GetAEAD() const113   const EVP_HPKE_AEAD *GetAEAD() const {
114     for (const auto aead : kAllAEADs) {
115       if (EVP_HPKE_AEAD_id(aead()) == aead_id_) {
116         return aead();
117       }
118     }
119     return nullptr;
120   }
121 
GetKDF() const122   const EVP_HPKE_KDF *GetKDF() const {
123     for (const auto kdf : kAllKDFs) {
124       if (EVP_HPKE_KDF_id(kdf()) == kdf_id_) {
125         return kdf();
126       }
127     }
128     return nullptr;
129   }
130 
VerifySender(EVP_HPKE_CTX * ctx) const131   void VerifySender(EVP_HPKE_CTX *ctx) const {
132     for (const Encryption &task : encryptions_) {
133       std::vector<uint8_t> encrypted(task.plaintext.size() +
134                                      EVP_HPKE_CTX_max_overhead(ctx));
135       size_t encrypted_len;
136       ASSERT_TRUE(EVP_HPKE_CTX_seal(ctx, encrypted.data(), &encrypted_len,
137                                     encrypted.size(), task.plaintext.data(),
138                                     task.plaintext.size(), task.aad.data(),
139                                     task.aad.size()));
140 
141       ASSERT_EQ(Bytes(encrypted.data(), encrypted_len), Bytes(task.ciphertext));
142     }
143     VerifyExports(ctx);
144   }
145 
VerifyRecipient(EVP_HPKE_CTX * ctx) const146   void VerifyRecipient(EVP_HPKE_CTX *ctx) const {
147     for (const Encryption &task : encryptions_) {
148       std::vector<uint8_t> decrypted(task.ciphertext.size());
149       size_t decrypted_len;
150       ASSERT_TRUE(EVP_HPKE_CTX_open(ctx, decrypted.data(), &decrypted_len,
151                                     decrypted.size(), task.ciphertext.data(),
152                                     task.ciphertext.size(), task.aad.data(),
153                                     task.aad.size()));
154 
155       ASSERT_EQ(Bytes(decrypted.data(), decrypted_len), Bytes(task.plaintext));
156     }
157     VerifyExports(ctx);
158   }
159 
VerifyExports(EVP_HPKE_CTX * ctx) const160   void VerifyExports(EVP_HPKE_CTX *ctx) const {
161     for (const Export &task : exports_) {
162       std::vector<uint8_t> exported_secret(task.export_length);
163 
164       ASSERT_TRUE(EVP_HPKE_CTX_export(
165           ctx, exported_secret.data(), exported_secret.size(),
166           task.exporter_context.data(), task.exporter_context.size()));
167       ASSERT_EQ(Bytes(exported_secret), Bytes(task.exported_value));
168     }
169   }
170 
171   struct Encryption {
172     std::vector<uint8_t> aad;
173     std::vector<uint8_t> ciphertext;
174     std::vector<uint8_t> plaintext;
175   };
176 
177   struct Export {
178     std::vector<uint8_t> exporter_context;
179     size_t export_length;
180     std::vector<uint8_t> exported_value;
181   };
182 
183   uint16_t kdf_id_;
184   uint16_t aead_id_;
185   std::vector<uint8_t> context_;
186   std::vector<uint8_t> info_;
187   std::vector<uint8_t> public_key_e_;
188   std::vector<uint8_t> secret_key_e_;
189   std::vector<uint8_t> public_key_r_;
190   std::vector<uint8_t> secret_key_r_;
191   std::vector<Encryption> encryptions_;
192   std::vector<Export> exports_;
193 };
194 
195 // Match FileTest's naming scheme for duplicated attribute names.
BuildAttrName(const std::string & name,int iter)196 std::string BuildAttrName(const std::string &name, int iter) {
197   return iter == 1 ? name : name + "/" + std::to_string(iter);
198 }
199 
200 // Parses |s| as an unsigned integer of type T and writes the value to |out|.
201 // Returns true on success. If the integer value exceeds the maximum T value,
202 // returns false.
203 template <typename T>
ParseIntSafe(T * out,const std::string & s)204 bool ParseIntSafe(T *out, const std::string &s) {
205   T value = 0;
206   for (char c : s) {
207     if (c < '0' || c > '9') {
208       return false;
209     }
210     if (value > (std::numeric_limits<T>::max() - (c - '0')) / 10) {
211       return false;
212     }
213     value = 10 * value + (c - '0');
214   }
215   *out = value;
216   return true;
217 }
218 
219 // Read the |key| attribute from |file_test| and convert it to an integer.
220 template <typename T>
FileTestReadInt(FileTest * file_test,T * out,const std::string & key)221 bool FileTestReadInt(FileTest *file_test, T *out, const std::string &key) {
222   std::string s;
223   return file_test->GetAttribute(&s, key) && ParseIntSafe(out, s);
224 }
225 
226 
ReadFromFileTest(FileTest * t)227 bool HPKETestVector::ReadFromFileTest(FileTest *t) {
228   uint8_t mode = 0;
229   if (!FileTestReadInt(t, &mode, "mode") ||
230       mode != 0 /* mode_base */ ||
231       !FileTestReadInt(t, &kdf_id_, "kdf_id") ||
232       !FileTestReadInt(t, &aead_id_, "aead_id") ||
233       !t->GetBytes(&info_, "info") ||
234       !t->GetBytes(&secret_key_r_, "skRm") ||
235       !t->GetBytes(&public_key_r_, "pkRm") ||
236       !t->GetBytes(&secret_key_e_, "skEm") ||
237       !t->GetBytes(&public_key_e_, "pkEm")) {
238     return false;
239   }
240 
241   for (int i = 1; t->HasAttribute(BuildAttrName("aad", i)); i++) {
242     Encryption encryption;
243     if (!t->GetBytes(&encryption.aad, BuildAttrName("aad", i)) ||
244         !t->GetBytes(&encryption.ciphertext, BuildAttrName("ciphertext", i)) ||
245         !t->GetBytes(&encryption.plaintext, BuildAttrName("plaintext", i))) {
246       return false;
247     }
248     encryptions_.push_back(std::move(encryption));
249   }
250 
251   for (int i = 1; t->HasAttribute(BuildAttrName("exporter_context", i)); i++) {
252     Export exp;
253     if (!t->GetBytes(&exp.exporter_context,
254                      BuildAttrName("exporter_context", i)) ||
255         !FileTestReadInt(t, &exp.export_length, BuildAttrName("L", i)) ||
256         !t->GetBytes(&exp.exported_value, BuildAttrName("exported_value", i))) {
257       return false;
258     }
259     exports_.push_back(std::move(exp));
260   }
261   return true;
262 }
263 
264 }  // namespace
265 
TEST(HPKETest,VerifyTestVectors)266 TEST(HPKETest, VerifyTestVectors) {
267   FileTestGTest("crypto/hpke/hpke_test_vectors.txt", [](FileTest *t) {
268     HPKETestVector test_vec;
269     EXPECT_TRUE(test_vec.ReadFromFileTest(t));
270     test_vec.Verify();
271   });
272 }
273 
274 // The test vectors used fixed sender ephemeral keys, while HPKE itself
275 // generates new keys for each context. Test this codepath by checking we can
276 // decrypt our own messages.
TEST(HPKETest,RoundTrip)277 TEST(HPKETest, RoundTrip) {
278   const uint8_t info_a[] = {1, 1, 2, 3, 5, 8};
279   const uint8_t info_b[] = {42, 42, 42};
280   const uint8_t ad_a[] = {1, 2, 4, 8, 16};
281   const uint8_t ad_b[] = {7};
282   Span<const uint8_t> info_values[] = {{nullptr, 0}, info_a, info_b};
283   Span<const uint8_t> ad_values[] = {{nullptr, 0}, ad_a, ad_b};
284 
285   // Generate the recipient's keypair.
286   ScopedEVP_HPKE_KEY key;
287   ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
288   uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
289   size_t public_key_r_len;
290   ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key_r,
291                                       &public_key_r_len, sizeof(public_key_r)));
292 
293   for (const auto kdf : kAllKDFs) {
294     SCOPED_TRACE(EVP_HPKE_KDF_id(kdf()));
295     for (const auto aead : kAllAEADs) {
296       SCOPED_TRACE(EVP_HPKE_AEAD_id(aead()));
297       for (const Span<const uint8_t> &info : info_values) {
298         SCOPED_TRACE(Bytes(info));
299         for (const Span<const uint8_t> &ad : ad_values) {
300           SCOPED_TRACE(Bytes(ad));
301           // Set up the sender.
302           ScopedEVP_HPKE_CTX sender_ctx;
303           uint8_t enc[X25519_PUBLIC_VALUE_LEN];
304           size_t enc_len;
305           ASSERT_TRUE(EVP_HPKE_CTX_setup_sender(
306               sender_ctx.get(), enc, &enc_len, sizeof(enc),
307               EVP_hpke_x25519_hkdf_sha256(), kdf(), aead(), public_key_r,
308               public_key_r_len, info.data(), info.size()));
309 
310           // Set up the recipient.
311           ScopedEVP_HPKE_CTX recipient_ctx;
312           ASSERT_TRUE(EVP_HPKE_CTX_setup_recipient(
313               recipient_ctx.get(), key.get(), kdf(), aead(), enc, enc_len,
314               info.data(), info.size()));
315 
316           const char kCleartextPayload[] = "foobar";
317 
318           // Have sender encrypt message for the recipient.
319           std::vector<uint8_t> ciphertext(
320               sizeof(kCleartextPayload) +
321               EVP_HPKE_CTX_max_overhead(sender_ctx.get()));
322           size_t ciphertext_len;
323           ASSERT_TRUE(EVP_HPKE_CTX_seal(
324               sender_ctx.get(), ciphertext.data(), &ciphertext_len,
325               ciphertext.size(),
326               reinterpret_cast<const uint8_t *>(kCleartextPayload),
327               sizeof(kCleartextPayload), ad.data(), ad.size()));
328 
329           // Have recipient decrypt the message.
330           std::vector<uint8_t> cleartext(ciphertext.size());
331           size_t cleartext_len;
332           ASSERT_TRUE(EVP_HPKE_CTX_open(recipient_ctx.get(), cleartext.data(),
333                                         &cleartext_len, cleartext.size(),
334                                         ciphertext.data(), ciphertext_len,
335                                         ad.data(), ad.size()));
336 
337           // Verify that decrypted message matches the original.
338           ASSERT_EQ(Bytes(cleartext.data(), cleartext_len),
339                     Bytes(kCleartextPayload, sizeof(kCleartextPayload)));
340         }
341       }
342     }
343   }
344 }
345 
346 // Verify that the DH operations inside Encap() and Decap() both fail when the
347 // public key is on a small-order point in the curve.
TEST(HPKETest,X25519EncapSmallOrderPoint)348 TEST(HPKETest, X25519EncapSmallOrderPoint) {
349   // Borrowed from X25519Test.SmallOrder.
350   static const uint8_t kSmallOrderPoint[32] = {
351       0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
352       0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
353       0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8,
354   };
355 
356   ScopedEVP_HPKE_KEY key;
357   ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
358 
359   for (const auto kdf : kAllKDFs) {
360     SCOPED_TRACE(EVP_HPKE_KDF_id(kdf()));
361     for (const auto aead : kAllAEADs) {
362       SCOPED_TRACE(EVP_HPKE_AEAD_id(aead()));
363       // Set up the sender, passing in kSmallOrderPoint as |peer_public_key|.
364       ScopedEVP_HPKE_CTX sender_ctx;
365       uint8_t enc[X25519_PUBLIC_VALUE_LEN];
366       size_t enc_len;
367       ASSERT_FALSE(EVP_HPKE_CTX_setup_sender(
368           sender_ctx.get(), enc, &enc_len, sizeof(enc),
369           EVP_hpke_x25519_hkdf_sha256(), kdf(), aead(), kSmallOrderPoint,
370           sizeof(kSmallOrderPoint), nullptr, 0));
371 
372       // Set up the recipient, passing in kSmallOrderPoint as |enc|.
373       ScopedEVP_HPKE_CTX recipient_ctx;
374       ASSERT_FALSE(EVP_HPKE_CTX_setup_recipient(
375           recipient_ctx.get(), key.get(), kdf(), aead(), kSmallOrderPoint,
376           sizeof(kSmallOrderPoint), nullptr, 0));
377     }
378   }
379 }
380 
381 // Test that Seal() fails when the context has been initialized as a recipient.
TEST(HPKETest,RecipientInvalidSeal)382 TEST(HPKETest, RecipientInvalidSeal) {
383   const uint8_t kMockEnc[X25519_PUBLIC_VALUE_LEN] = {0xff};
384   const char kCleartextPayload[] = "foobar";
385 
386   ScopedEVP_HPKE_KEY key;
387   ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
388 
389   // Set up the recipient.
390   ScopedEVP_HPKE_CTX recipient_ctx;
391   ASSERT_TRUE(EVP_HPKE_CTX_setup_recipient(
392       recipient_ctx.get(), key.get(), EVP_hpke_hkdf_sha256(),
393       EVP_hpke_aes_128_gcm(), kMockEnc, sizeof(kMockEnc), nullptr, 0));
394 
395   // Call Seal() on the recipient.
396   size_t ciphertext_len;
397   uint8_t ciphertext[100];
398   ASSERT_FALSE(EVP_HPKE_CTX_seal(
399       recipient_ctx.get(), ciphertext, &ciphertext_len, sizeof(ciphertext),
400       reinterpret_cast<const uint8_t *>(kCleartextPayload),
401       sizeof(kCleartextPayload), nullptr, 0));
402 }
403 
404 // Test that Open() fails when the context has been initialized as a sender.
TEST(HPKETest,SenderInvalidOpen)405 TEST(HPKETest, SenderInvalidOpen) {
406   const uint8_t kMockCiphertext[100] = {0xff};
407   const size_t kMockCiphertextLen = 80;
408 
409   // Generate the recipient's keypair.
410   uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
411   uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
412   X25519_keypair(public_key_r, secret_key_r);
413 
414   // Set up the sender.
415   ScopedEVP_HPKE_CTX sender_ctx;
416   uint8_t enc[X25519_PUBLIC_VALUE_LEN];
417   size_t enc_len;
418   ASSERT_TRUE(EVP_HPKE_CTX_setup_sender(
419       sender_ctx.get(), enc, &enc_len, sizeof(enc),
420       EVP_hpke_x25519_hkdf_sha256(), EVP_hpke_hkdf_sha256(),
421       EVP_hpke_aes_128_gcm(), public_key_r, sizeof(public_key_r), nullptr, 0));
422 
423   // Call Open() on the sender.
424   uint8_t cleartext[128];
425   size_t cleartext_len;
426   ASSERT_FALSE(EVP_HPKE_CTX_open(sender_ctx.get(), cleartext, &cleartext_len,
427                                  sizeof(cleartext), kMockCiphertext,
428                                  kMockCiphertextLen, nullptr, 0));
429 }
430 
TEST(HPKETest,SetupSenderBufferTooSmall)431 TEST(HPKETest, SetupSenderBufferTooSmall) {
432   uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
433   uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
434   X25519_keypair(public_key_r, secret_key_r);
435 
436   ScopedEVP_HPKE_CTX sender_ctx;
437   uint8_t enc[X25519_PUBLIC_VALUE_LEN - 1];
438   size_t enc_len;
439   ASSERT_FALSE(EVP_HPKE_CTX_setup_sender(
440       sender_ctx.get(), enc, &enc_len, sizeof(enc),
441       EVP_hpke_x25519_hkdf_sha256(), EVP_hpke_hkdf_sha256(),
442       EVP_hpke_aes_128_gcm(), public_key_r, sizeof(public_key_r), nullptr, 0));
443   uint32_t err = ERR_get_error();
444   EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
445   EXPECT_EQ(EVP_R_INVALID_BUFFER_SIZE, ERR_GET_REASON(err));
446   ERR_clear_error();
447 }
448 
TEST(HPKETest,SetupSenderBufferTooLarge)449 TEST(HPKETest, SetupSenderBufferTooLarge) {
450   uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
451   uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
452   X25519_keypair(public_key_r, secret_key_r);
453 
454   // Too large of an output buffer is fine because the function reports the
455   // actual length.
456   ScopedEVP_HPKE_CTX sender_ctx;
457   uint8_t enc[X25519_PUBLIC_VALUE_LEN + 1];
458   size_t enc_len;
459   EXPECT_TRUE(EVP_HPKE_CTX_setup_sender(
460       sender_ctx.get(), enc, &enc_len, sizeof(enc),
461       EVP_hpke_x25519_hkdf_sha256(), EVP_hpke_hkdf_sha256(),
462       EVP_hpke_aes_128_gcm(), public_key_r, sizeof(public_key_r), nullptr, 0));
463   EXPECT_EQ(size_t{X25519_PUBLIC_VALUE_LEN}, enc_len);
464 }
465 
TEST(HPKETest,SetupRecipientWrongLengthEnc)466 TEST(HPKETest, SetupRecipientWrongLengthEnc) {
467   ScopedEVP_HPKE_KEY key;
468   ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
469 
470   const uint8_t bogus_enc[X25519_PUBLIC_VALUE_LEN + 5] = {0xff};
471 
472   ScopedEVP_HPKE_CTX recipient_ctx;
473   ASSERT_FALSE(EVP_HPKE_CTX_setup_recipient(
474       recipient_ctx.get(), key.get(), EVP_hpke_hkdf_sha256(),
475       EVP_hpke_aes_128_gcm(), bogus_enc, sizeof(bogus_enc), nullptr, 0));
476   uint32_t err = ERR_get_error();
477   EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
478   EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
479   ERR_clear_error();
480 }
481 
TEST(HPKETest,SetupSenderWrongLengthPeerPublicValue)482 TEST(HPKETest, SetupSenderWrongLengthPeerPublicValue) {
483   const uint8_t bogus_public_key_r[X25519_PRIVATE_KEY_LEN + 5] = {0xff};
484   ScopedEVP_HPKE_CTX sender_ctx;
485   uint8_t enc[X25519_PUBLIC_VALUE_LEN];
486   size_t enc_len;
487   ASSERT_FALSE(EVP_HPKE_CTX_setup_sender(
488       sender_ctx.get(), enc, &enc_len, sizeof(enc),
489       EVP_hpke_x25519_hkdf_sha256(), EVP_hpke_hkdf_sha256(),
490       EVP_hpke_aes_128_gcm(), bogus_public_key_r, sizeof(bogus_public_key_r),
491       nullptr, 0));
492   uint32_t err = ERR_get_error();
493   EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
494   EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
495   ERR_clear_error();
496 }
497 
TEST(HPKETest,InvalidRecipientKey)498 TEST(HPKETest, InvalidRecipientKey) {
499   const uint8_t private_key[X25519_PUBLIC_VALUE_LEN + 5] = {0xff};
500   ScopedEVP_HPKE_KEY key;
501   EXPECT_FALSE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
502                                  private_key, sizeof(private_key)));
503 }
504 
TEST(HPKETest,InternalParseIntSafe)505 TEST(HPKETest, InternalParseIntSafe) {
506   uint8_t u8 = 0xff;
507   ASSERT_FALSE(ParseIntSafe(&u8, "-1"));
508 
509   ASSERT_TRUE(ParseIntSafe(&u8, "0"));
510   ASSERT_EQ(u8, 0);
511 
512   ASSERT_TRUE(ParseIntSafe(&u8, "255"));
513   ASSERT_EQ(u8, 255);
514 
515   ASSERT_FALSE(ParseIntSafe(&u8, "256"));
516 
517   uint16_t u16 = 0xffff;
518   ASSERT_TRUE(ParseIntSafe(&u16, "257"));
519   ASSERT_EQ(u16, 257);
520 
521   ASSERT_TRUE(ParseIntSafe(&u16, "65535"));
522   ASSERT_EQ(u16, 65535);
523 
524   ASSERT_FALSE(ParseIntSafe(&u16, "65536"));
525 }
526 
527 
528 }  // namespace bssl
529