1#![deny(warnings, unconditional_panic)]
5#![deny(nonstandard_style)]
6#![deny(clippy::all)]
7
8#[allow(non_snake_case)]
9pub mod Signature {
10 pub mod ECDSA {
11 use crate::software::amazon::cryptography::primitives::internaldafny::types::ECDSASignatureAlgorithm;
12 use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError;
13 use crate::*;
14 use aws_lc_rs::encoding::AsDer;
15 use aws_lc_rs::rand::SystemRandom;
16 use aws_lc_rs::signature::EcdsaKeyPair;
17 use aws_lc_rs::signature::EcdsaSigningAlgorithm;
18 use aws_lc_rs::signature::EcdsaVerificationAlgorithm;
19 use aws_lc_rs::signature::KeyPair;
20 use aws_lc_rs::signature::UnparsedPublicKey;
21 use dafny_runtime::Rc;
22
23 fn error(s: &str) -> Rc<DafnyError> {
24 Rc::new(DafnyError::AwsCryptographicPrimitivesError {
25 message:
26 dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(s),
27 })
28 }
29
30 fn get_alg(x: &ECDSASignatureAlgorithm) -> &'static EcdsaSigningAlgorithm {
31 match x {
32 ECDSASignatureAlgorithm::ECDSA_P256 {} => {
33 &aws_lc_rs::signature::ECDSA_P256_SHA256_ASN1_SIGNING
35 }
36 ECDSASignatureAlgorithm::ECDSA_P384 {} => {
37 &aws_lc_rs::signature::ECDSA_P384_SHA384_ASN1_SIGNING
39 }
40 }
41 }
42
43 fn get_ver_alg(x: &ECDSASignatureAlgorithm) -> &'static EcdsaVerificationAlgorithm {
44 match x {
45 ECDSASignatureAlgorithm::ECDSA_P256 {} => {
46 &aws_lc_rs::signature::ECDSA_P256_SHA256_ASN1
48 }
49 ECDSASignatureAlgorithm::ECDSA_P384 {} => {
50 &aws_lc_rs::signature::ECDSA_P384_SHA384_ASN1
52 }
53 }
54 }
55
56 fn get_nid(x: &ECDSASignatureAlgorithm) -> i32 {
57 match x {
58 ECDSASignatureAlgorithm::ECDSA_P256 {} => aws_lc_sys_impl::NID_X9_62_prime256v1,
59 ECDSASignatureAlgorithm::ECDSA_P384 {} => aws_lc_sys_impl::NID_secp384r1,
60 }
61 }
62
63 const ELEM_MAX_BITS: usize = 521;
64 const ELEM_MAX_BYTES: usize = ELEM_MAX_BITS.div_ceil(8);
65 const PUBLIC_KEY_MAX_LEN: usize = 1 + (2 * ELEM_MAX_BYTES);
66
67 pub(crate) fn sec1_compress(
68 data: &[u8],
69 alg: &ECDSASignatureAlgorithm,
70 ) -> Result<Vec<u8>, String> {
71 sec1_convert(
72 data,
73 get_nid(alg),
74 aws_lc_sys_impl::point_conversion_form_t::POINT_CONVERSION_COMPRESSED,
75 )
76 }
77
78 pub(crate) fn sec1_convert(
79 data: &[u8],
80 nid: i32,
81 form: aws_lc_sys_impl::point_conversion_form_t,
82 ) -> Result<Vec<u8>, String> {
83 use aws_lc_sys_impl::EC_GROUP_new_by_curve_name;
84 use aws_lc_sys_impl::EC_POINT_free;
85 use aws_lc_sys_impl::EC_POINT_new;
86 use aws_lc_sys_impl::EC_POINT_oct2point;
87 use aws_lc_sys_impl::EC_POINT_point2oct;
88 use std::ptr::null_mut;
89
90 let ec_group = unsafe { EC_GROUP_new_by_curve_name(nid) };
92 if ec_group.is_null() {
93 return Err("EC_GROUP_new_by_curve_name returned failure.".to_string());
94 }
95
96 let ec_point = unsafe { EC_POINT_new(ec_group) };
97 if ec_point.is_null() {
98 return Err("EC_POINT_new returned failure.".to_string());
99 }
100 let mut out_buf = [0u8; PUBLIC_KEY_MAX_LEN];
101
102 let ret = unsafe {
103 EC_POINT_oct2point(ec_group, ec_point, data.as_ptr(), data.len(), null_mut())
104 };
105 if ret == 0 {
106 return Err("EC_POINT_oct2point returned failure.".to_string());
107 }
108 let new_size: usize = unsafe {
109 EC_POINT_point2oct(
110 ec_group,
111 ec_point,
112 form,
113 out_buf.as_mut_ptr(),
114 PUBLIC_KEY_MAX_LEN,
115 null_mut(),
116 )
117 };
118 unsafe { EC_POINT_free(ec_point) };
119 Ok(out_buf[..new_size].to_vec())
120 }
121
122 fn ecdsa_key_gen(alg: &ECDSASignatureAlgorithm) -> Result<(Vec<u8>, Vec<u8>), String> {
123 let pair = EcdsaKeyPair::generate(get_alg(alg)).map_err(|e| format!("{e:?}"))?;
124
125 let public_key: Vec<u8> = sec1_compress(pair.public_key().as_ref(), alg)?;
126 let private_key: Vec<u8> = pair.private_key().as_der().unwrap().as_ref().to_vec();
127 Ok((public_key, private_key))
128 }
129
130 pub fn ExternKeyGen(
131 alg: &Rc<ECDSASignatureAlgorithm>,
132 ) -> Rc<_Wrappers_Compile::Result<Rc<Signature::SignatureKeyPair>, Rc<DafnyError>>>
133 {
134 match ecdsa_key_gen(alg) {
135 Ok(x) => Rc::new(_Wrappers_Compile::Result::Success {
136 value: Rc::new(Signature::SignatureKeyPair::SignatureKeyPair {
137 verificationKey: dafny_runtime::Sequence::from_array_owned(x.0),
138 signingKey: dafny_runtime::Sequence::from_array_owned(x.1),
139 }),
140 }),
141 Err(e) => {
142 let msg = format!("ECDSA Key Gen : {e}");
143 Rc::new(_Wrappers_Compile::Result::Failure { error: error(&msg) })
144 }
145 }
146 }
147
148 fn ecdsa_sign_inner(
149 alg: &ECDSASignatureAlgorithm,
150 key: &[u8],
151 msg: &[u8],
152 ) -> Result<Vec<u8>, String> {
153 let private_key = EcdsaKeyPair::from_private_key_der(get_alg(alg), key)
154 .map_err(|e| format!("{e:?}"))?;
155 let rng = SystemRandom::new();
156 let sig = private_key.sign(&rng, msg).map_err(|e| format!("{e:?}"))?;
157 Ok(sig.as_ref().to_vec())
158 }
159 fn ecdsa_sign(
160 alg: &ECDSASignatureAlgorithm,
161 key: &[u8],
162 msg: &[u8],
163 ) -> Result<Vec<u8>, String> {
164 loop {
167 let result = ecdsa_sign_inner(alg, key, msg)?;
168 if (get_alg(alg) == &aws_lc_rs::signature::ECDSA_P384_SHA384_ASN1_SIGNING
169 && result.len() == 103)
170 || (get_alg(alg) == &aws_lc_rs::signature::ECDSA_P256_SHA256_ASN1_SIGNING
171 && result.len() == 71)
172 {
173 return Ok(result);
174 }
175 }
176 }
177
178 pub fn Sign(
179 alg: &Rc<ECDSASignatureAlgorithm>,
180 key: &::dafny_runtime::Sequence<u8>,
181 msg: &::dafny_runtime::Sequence<u8>,
182 ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence<u8>, Rc<DafnyError>>> {
183 let key = &key.to_array();
184 let msg = &msg.to_array();
185 match ecdsa_sign(alg, key, msg) {
186 Ok(x) => Rc::new(_Wrappers_Compile::Result::Success {
187 value: dafny_runtime::Sequence::from_array_owned(x),
188 }),
189 Err(e) => {
190 let msg = format!("ECDSA Sign : {e}");
191 Rc::new(_Wrappers_Compile::Result::Failure { error: error(&msg) })
192 }
193 }
194 }
195
196 fn ecdsa_verify(
197 alg: &ECDSASignatureAlgorithm,
198 key: &[u8],
199 msg: &[u8],
200 sig: &[u8],
201 ) -> Result<bool, String> {
202 let public_key = UnparsedPublicKey::new(get_ver_alg(alg), key);
203 match public_key.verify(msg, sig) {
204 Ok(_) => Ok(true),
205 Err(_) => Ok(false),
206 }
207 }
208
209 pub fn Verify(
210 alg: &Rc<ECDSASignatureAlgorithm>,
211 key: &::dafny_runtime::Sequence<u8>,
212 msg: &::dafny_runtime::Sequence<u8>,
213 sig: &::dafny_runtime::Sequence<u8>,
214 ) -> Rc<_Wrappers_Compile::Result<bool, Rc<DafnyError>>> {
215 let key = &key.to_array();
216 let msg = &msg.to_array();
217 let sig = &sig.to_array();
218 match ecdsa_verify(alg, key, msg, sig) {
219 Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { value: x }),
220 Err(e) => {
221 let msg = format!("ECDSA Verify : {e}");
222 Rc::new(_Wrappers_Compile::Result::Failure { error: error(&msg) })
223 }
224 }
225 }
226 #[cfg(test)]
227 mod tests {
228 use super::*;
229 use dafny_runtime::Rc;
230
231 #[test]
232 fn test_generate() {
233 let alg = Rc::new(ECDSASignatureAlgorithm::ECDSA_P384 {});
234 let key_pair = match &*ExternKeyGen(&alg) {
235 _Wrappers_Compile::Result::Success { value } => value.clone(),
236 _Wrappers_Compile::Result::Failure { error } => {
237 panic!("ExternKeyGen Failed : {error:?}");
238 }
239 };
240
241 let (s_key, v_key) = match &*key_pair {
242 Signature::SignatureKeyPair::SignatureKeyPair {
243 signingKey,
244 verificationKey,
245 } => (signingKey, verificationKey),
246 };
247
248 let message: ::dafny_runtime::Sequence<u8> =
249 dafny_runtime::Sequence::from_array_owned(vec![1u8, 2, 3, 4, 5]);
250
251 let sig = match &*Sign(&alg, s_key, &message) {
252 _Wrappers_Compile::Result::Success { value } => value.clone(),
253 _Wrappers_Compile::Result::Failure { error } => {
254 panic!("Sign Failed : {error:?}");
255 }
256 };
257
258 let ver: bool = match &*Verify(&alg, v_key, &message, &sig) {
259 _Wrappers_Compile::Result::Success { value } => *value,
260 _Wrappers_Compile::Result::Failure { error } => {
261 panic!("Verify Failed : {error:?}");
262 }
263 };
264 assert!(ver);
265
266 let mut sig_vec: Vec<u8> = sig.iter().collect();
267 sig_vec[0] = 42;
268 let sig2: ::dafny_runtime::Sequence<u8> = sig_vec.iter().cloned().collect();
269 assert!(sig != sig2);
270 let ver2: bool = match &*Verify(&alg, v_key, &message, &sig2) {
271 _Wrappers_Compile::Result::Success { value } => *value,
272 _Wrappers_Compile::Result::Failure { error } => {
273 panic!("Verify Failed : {error:?}");
274 }
275 };
276 assert!(!ver2);
277 }
278 }
279 }
280}