Botan 3.11.0
Crypto and TLS for C&
ffi_srp6.cpp
Go to the documentation of this file.
1/*
2* (C) 2022 Rostyslav Khudolii
3* 2023 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/ffi.h>
9
10#include <botan/assert.h>
11#include <botan/internal/ffi_rng.h>
12#include <botan/internal/ffi_util.h>
13
14#if defined(BOTAN_HAS_SRP6)
15 #include <botan/bigint.h>
16 #include <botan/dl_group.h>
17 #include <botan/rng.h>
18 #include <botan/srp6.h>
19 #include <botan/symkey.h>
20#endif
21
22extern "C" {
23
24using namespace Botan_FFI;
25
26#if defined(BOTAN_HAS_SRP6)
27BOTAN_FFI_DECLARE_STRUCT(botan_srp6_server_session_struct, Botan::SRP6_Server_Session, 0x44F7425F);
28#else
29BOTAN_FFI_DECLARE_DUMMY_STRUCT(botan_srp6_server_session_struct, 0x44F7425F);
30#endif
31
33#if defined(BOTAN_HAS_SRP6)
34 return ffi_guard_thunk(
35 __func__, [=]() -> int { return ffi_new_object(srp6, std::make_unique<Botan::SRP6_Server_Session>()); });
36#else
37 BOTAN_UNUSED(srp6);
39#endif
40}
41
45
46int botan_srp6_group_size(const char* group_id, size_t* group_p_bytes) {
47#if defined(BOTAN_HAS_SRP6)
48 if(any_null_pointers(group_id, group_p_bytes)) {
50 }
51
52 return ffi_guard_thunk(__func__, [=]() -> int {
53 const auto group = Botan::DL_Group::from_name(group_id);
54 *group_p_bytes = group.p_bytes();
55 return BOTAN_FFI_SUCCESS;
56 });
57#else
58 BOTAN_UNUSED(group_id, group_p_bytes);
60#endif
61}
62
64 const uint8_t* verifier,
65 size_t verifier_len,
66 const char* group_id,
67 const char* hash_id,
68 botan_rng_t rng_obj,
69 uint8_t b_pub[],
70 size_t* b_pub_len) {
71#if defined(BOTAN_HAS_SRP6)
72 return BOTAN_FFI_VISIT(srp6, [=](auto& s) -> int {
73 if(any_null_pointers(verifier, group_id, hash_id, rng_obj)) {
75 }
76 try {
77 const auto group = Botan::DL_Group::from_name(group_id);
78 const auto rc = check_and_prepare_output_space(b_pub, b_pub_len, group.p_bytes());
79 if(rc != BOTAN_FFI_SUCCESS) {
80 return rc;
81 }
82
84 auto v_bn = Botan::BigInt::from_bytes(std::span{verifier, verifier_len});
85 auto b_pub_bn = s.step1(v_bn, group, hash_id, group.exponent_bits(), rng);
86 return write_vec_output(b_pub, b_pub_len, b_pub_bn.serialize(group.p_bytes()));
87 } catch(Botan::Decoding_Error&) {
89 } catch(Botan::Lookup_Error&) {
91 }
92 });
93#else
94 BOTAN_UNUSED(srp6, verifier, verifier_len, group_id, hash_id, rng_obj, b_pub, b_pub_len);
96#endif
97}
98
100 botan_srp6_server_session_t srp6, const uint8_t a[], size_t a_len, uint8_t key[], size_t* key_len) {
101#if defined(BOTAN_HAS_SRP6)
102 return BOTAN_FFI_VISIT(srp6, [=](auto& s) -> int {
103 if(!a) {
105 }
106 try {
107 const Botan::BigInt a_bn = Botan::BigInt::from_bytes({a, a_len});
108 auto key_sk = s.step2(a_bn);
109 return write_vec_output(key, key_len, key_sk.bits_of());
110 } catch(Botan::Decoding_Error&) {
112 }
113 });
114#else
115 BOTAN_UNUSED(srp6, a, a_len, key, key_len);
117#endif
118}
119
120int botan_srp6_generate_verifier(const char* username,
121 const char* password,
122 const uint8_t salt[],
123 size_t salt_len,
124 const char* group_id,
125 const char* hash_id,
126 uint8_t verifier[],
127 size_t* verifier_len) {
128#if defined(BOTAN_HAS_SRP6)
129 return ffi_guard_thunk(__func__, [=]() -> int {
130 if(any_null_pointers(username, password, salt, group_id, hash_id)) {
132 }
133 try {
134 const std::vector<uint8_t> salt_vec(salt, salt + salt_len);
135 const auto group = Botan::DL_Group::from_name(group_id);
136 const size_t p_bytes = group.p_bytes();
137 auto verifier_bn = Botan::srp6_generate_verifier(username, password, salt_vec, group, hash_id);
138 return write_vec_output(verifier, verifier_len, verifier_bn.serialize(p_bytes));
139 } catch(Botan::Lookup_Error&) {
141 }
142 });
143#else
144 BOTAN_UNUSED(username, password, group_id, hash_id);
145 BOTAN_UNUSED(salt, salt_len, verifier, verifier_len);
147#endif
148}
149
150int botan_srp6_client_agree(const char* identity,
151 const char* password,
152 const char* group_id,
153 const char* hash_id,
154 const uint8_t salt[],
155 size_t salt_len,
156 const uint8_t b[],
157 size_t b_len,
158 botan_rng_t rng_obj,
159 uint8_t A[],
160 size_t* A_len,
161 uint8_t K[],
162 size_t* K_len) {
163#if defined(BOTAN_HAS_SRP6)
164 return ffi_guard_thunk(__func__, [=]() -> int {
165 if(any_null_pointers(identity, password, salt, group_id, hash_id, b, rng_obj)) {
167 }
168 try {
169 const std::vector<uint8_t> saltv(salt, salt + salt_len);
171 auto b_bn = Botan::BigInt::from_bytes({b, b_len});
172 const auto group = Botan::DL_Group::from_name(group_id);
173 const size_t a_bits = group.exponent_bits();
174 auto [A_bn, K_sk] = Botan::srp6_client_agree(identity, password, group, hash_id, saltv, b_bn, a_bits, rng);
175 auto ret_a = write_vec_output(A, A_len, A_bn.serialize(group.p_bytes()));
176 auto ret_k = write_vec_output(K, K_len, K_sk.bits_of());
177 if(ret_a != BOTAN_FFI_SUCCESS) {
178 return ret_a;
179 }
180 if(ret_k != BOTAN_FFI_SUCCESS) {
181 return ret_k;
182 }
183 return BOTAN_FFI_SUCCESS;
184 } catch(Botan::Lookup_Error&) {
186 }
187 });
188#else
189 BOTAN_UNUSED(identity, password, group_id, hash_id, rng_obj);
190 BOTAN_UNUSED(salt, salt_len, b, b_len, A, A_len, K, K_len);
192#endif
193}
194}
#define BOTAN_UNUSED
Definition assert.h:144
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
static DL_Group from_name(std::string_view name)
Definition dl_group.cpp:217
struct botan_srp6_server_session_struct * botan_srp6_server_session_t
Definition ffi.h:2873
struct botan_rng_struct * botan_rng_t
Definition ffi.h:291
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:140
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:133
@ BOTAN_FFI_SUCCESS
Definition ffi.h:116
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:134
int botan_srp6_server_session_step2(botan_srp6_server_session_t srp6, const uint8_t a[], size_t a_len, uint8_t key[], size_t *key_len)
Definition ffi_srp6.cpp:99
int botan_srp6_server_session_init(botan_srp6_server_session_t *srp6)
Definition ffi_srp6.cpp:32
int botan_srp6_server_session_destroy(botan_srp6_server_session_t srp6)
Definition ffi_srp6.cpp:42
int botan_srp6_group_size(const char *group_id, size_t *group_p_bytes)
Definition ffi_srp6.cpp:46
int botan_srp6_server_session_step1(botan_srp6_server_session_t srp6, const uint8_t *verifier, size_t verifier_len, const char *group_id, const char *hash_id, botan_rng_t rng_obj, uint8_t b_pub[], size_t *b_pub_len)
Definition ffi_srp6.cpp:63
int botan_srp6_generate_verifier(const char *username, const char *password, const uint8_t salt[], size_t salt_len, const char *group_id, const char *hash_id, uint8_t verifier[], size_t *verifier_len)
Definition ffi_srp6.cpp:120
int botan_srp6_client_agree(const char *identity, const char *password, const char *group_id, const char *hash_id, const uint8_t salt[], size_t salt_len, const uint8_t b[], size_t b_len, botan_rng_t rng_obj, uint8_t A[], size_t *A_len, uint8_t K[], size_t *K_len)
Definition ffi_srp6.cpp:150
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:158
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:185
#define BOTAN_FFI_DECLARE_DUMMY_STRUCT(NAME, MAGIC)
Definition ffi_util.h:66
#define BOTAN_FFI_DECLARE_STRUCT(NAME, TYPE, MAGIC)
Definition ffi_util.h:61
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:79
BOTAN_FFI_ERROR ffi_new_object(T *obj, Args &&... args)
Definition ffi_util.h:178
int ffi_guard_thunk(const char *func_name, T thunk)
Definition ffi_util.h:95
int write_vec_output(uint8_t out[], size_t *out_len, std::span< const uint8_t > buf)
Definition ffi_util.h:261
int check_and_prepare_output_space(T out[], size_t *out_len, size_t required_len)
Definition ffi_util.h:227
bool any_null_pointers(Ptrs... ptr)
Definition mem_utils.h:54
std::pair< BigInt, SymmetricKey > srp6_client_agree(std::string_view identifier, std::string_view password, std::string_view group_id, std::string_view hash_id, const std::vector< uint8_t > &salt, const BigInt &B, RandomNumberGenerator &rng)
Definition srp6.cpp:66
BigInt srp6_generate_verifier(std::string_view identifier, std::string_view password, const std::vector< uint8_t > &salt, std::string_view group_id, std::string_view hash_id)
Definition srp6.cpp:129