Branch data Line data Source code
1 : : /*
2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License").
5 : : * You may not use this file except in compliance with the License.
6 : : * A copy of the License is located at
7 : : *
8 : : * http://aws.amazon.com/apache2.0
9 : : *
10 : : * or in the "license" file accompanying this file. This file is distributed
11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 : : * express or implied. See the License for the specific language governing
13 : : * permissions and limitations under the License.
14 : : */
15 : :
16 : : #include <openssl/evp.h>
17 : : #include <stddef.h>
18 : :
19 : : #include "crypto/s2n_pq.h"
20 : : #include "error/s2n_errno.h"
21 : : #include "tls/s2n_kem.h"
22 : : #include "utils/s2n_safety.h"
23 : : #include "utils/s2n_safety_macros.h"
24 : :
25 : : #if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_KEM)
26 : :
27 : : DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY *, EVP_PKEY_free);
28 : : DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY_CTX *, EVP_PKEY_CTX_free);
29 : :
30 : : int s2n_evp_kem_generate_keypair(IN const struct s2n_kem *kem, OUT uint8_t *public_key,
31 : : OUT uint8_t *secret_key)
32 : : {
33 : : POSIX_ENSURE_REF(kem);
34 : : POSIX_ENSURE(kem->kem_nid != NID_undef, S2N_ERR_UNIMPLEMENTED);
35 : : DEFER_CLEANUP(EVP_PKEY_CTX *kem_pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_KEM, NULL), EVP_PKEY_CTX_free_pointer);
36 : : POSIX_ENSURE_REF(kem_pkey_ctx);
37 : : POSIX_GUARD_OSSL(EVP_PKEY_CTX_kem_set_params(kem_pkey_ctx, kem->kem_nid), S2N_ERR_PQ_CRYPTO);
38 : : POSIX_GUARD_OSSL(EVP_PKEY_keygen_init(kem_pkey_ctx), S2N_ERR_PQ_CRYPTO);
39 : :
40 : : DEFER_CLEANUP(EVP_PKEY *kem_pkey = NULL, EVP_PKEY_free_pointer);
41 : : POSIX_GUARD_OSSL(EVP_PKEY_keygen(kem_pkey_ctx, &kem_pkey), S2N_ERR_PQ_CRYPTO);
42 : : POSIX_ENSURE_REF(kem_pkey);
43 : :
44 : : size_t public_key_size = kem->public_key_length;
45 : : POSIX_GUARD_OSSL(EVP_PKEY_get_raw_public_key(kem_pkey, public_key, &public_key_size), S2N_ERR_PQ_CRYPTO);
46 : : POSIX_ENSURE_EQ(kem->public_key_length, public_key_size);
47 : : size_t private_key_size = kem->private_key_length;
48 : : POSIX_GUARD_OSSL(EVP_PKEY_get_raw_private_key(kem_pkey, secret_key, &private_key_size), S2N_ERR_PQ_CRYPTO);
49 : : POSIX_ENSURE_EQ(kem->private_key_length, private_key_size);
50 : :
51 : : return S2N_SUCCESS;
52 : : }
53 : :
54 : : int s2n_evp_kem_encapsulate(IN const struct s2n_kem *kem, OUT uint8_t *ciphertext, OUT uint8_t *shared_secret,
55 : : IN const uint8_t *public_key)
56 : : {
57 : : POSIX_ENSURE_REF(kem);
58 : : POSIX_ENSURE(kem->kem_nid != NID_undef, S2N_ERR_UNIMPLEMENTED);
59 : : DEFER_CLEANUP(EVP_PKEY *kem_pkey = EVP_PKEY_kem_new_raw_public_key(kem->kem_nid, public_key, kem->public_key_length), EVP_PKEY_free_pointer);
60 : : POSIX_ENSURE_REF(kem_pkey);
61 : :
62 : : DEFER_CLEANUP(EVP_PKEY_CTX *kem_pkey_ctx = EVP_PKEY_CTX_new(kem_pkey, NULL), EVP_PKEY_CTX_free_pointer);
63 : : POSIX_ENSURE_REF(kem_pkey_ctx);
64 : :
65 : : size_t ciphertext_size = kem->ciphertext_length;
66 : : size_t shared_secret_size = kem->shared_secret_key_length;
67 : : POSIX_GUARD_OSSL(EVP_PKEY_encapsulate(kem_pkey_ctx, ciphertext, &ciphertext_size, shared_secret,
68 : : &shared_secret_size),
69 : : S2N_ERR_PQ_CRYPTO);
70 : : POSIX_ENSURE_EQ(kem->ciphertext_length, ciphertext_size);
71 : : POSIX_ENSURE_EQ(kem->shared_secret_key_length, shared_secret_size);
72 : :
73 : : return S2N_SUCCESS;
74 : : }
75 : :
76 : : int s2n_evp_kem_decapsulate(IN const struct s2n_kem *kem, OUT uint8_t *shared_secret, IN const uint8_t *ciphertext,
77 : : IN const uint8_t *private_key)
78 : : {
79 : : POSIX_ENSURE_REF(kem);
80 : : POSIX_ENSURE(kem->kem_nid != NID_undef, S2N_ERR_UNIMPLEMENTED);
81 : : DEFER_CLEANUP(EVP_PKEY *kem_pkey = EVP_PKEY_kem_new_raw_secret_key(kem->kem_nid, private_key, kem->private_key_length), EVP_PKEY_free_pointer);
82 : : POSIX_ENSURE_REF(kem_pkey);
83 : :
84 : : DEFER_CLEANUP(EVP_PKEY_CTX *kem_pkey_ctx = EVP_PKEY_CTX_new(kem_pkey, NULL), EVP_PKEY_CTX_free_pointer);
85 : : POSIX_ENSURE_REF(kem_pkey_ctx);
86 : :
87 : : size_t shared_secret_size = kem->shared_secret_key_length;
88 : : POSIX_GUARD_OSSL(EVP_PKEY_decapsulate(kem_pkey_ctx, shared_secret, &shared_secret_size,
89 : : (uint8_t *) (uintptr_t) ciphertext, kem->ciphertext_length),
90 : : S2N_ERR_PQ_CRYPTO);
91 : : POSIX_ENSURE_EQ(kem->shared_secret_key_length, shared_secret_size);
92 : :
93 : : return S2N_SUCCESS;
94 : : }
95 : :
96 : : #else /* If !S2N_LIBCRYPTO_SUPPORTS_EVP_KEM, we won't have a kem impl so define relevant stubs here. */
97 : :
98 : : int s2n_evp_kem_generate_keypair(IN const struct s2n_kem *kem, OUT uint8_t *public_key,
99 : : OUT uint8_t *private_key)
100 : 5 : {
101 [ + - ]: 5 : POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
102 : 5 : }
103 : :
104 : : int s2n_evp_kem_encapsulate(IN const struct s2n_kem *kem, OUT uint8_t *ciphertext, OUT uint8_t *shared_secret,
105 : : IN const uint8_t *public_key)
106 : 5 : {
107 [ + - ]: 5 : POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
108 : 5 : }
109 : :
110 : : int s2n_evp_kem_decapsulate(IN const struct s2n_kem *kem, OUT uint8_t *shared_secret, IN const uint8_t *ciphertext,
111 : : IN const uint8_t *private_key)
112 : 5 : {
113 [ + - ]: 5 : POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
114 : 5 : }
115 : :
116 : : #endif
|