1use aws_lc_rs::{signature, try_fips_mode};
2use pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm, alg_id};
3
4#[derive(Debug)]
9struct AwsLcRsAlgorithm {
10 public_key_alg_id: AlgorithmIdentifier,
11 signature_alg_id: AlgorithmIdentifier,
12 verification_alg: &'static dyn signature::VerificationAlgorithm,
13 in_fips_submission: bool,
14}
15
16impl SignatureVerificationAlgorithm for AwsLcRsAlgorithm {
17 fn public_key_alg_id(&self) -> AlgorithmIdentifier {
18 self.public_key_alg_id
19 }
20
21 fn signature_alg_id(&self) -> AlgorithmIdentifier {
22 self.signature_alg_id
23 }
24
25 fn verify_signature(
26 &self,
27 public_key: &[u8],
28 message: &[u8],
29 signature: &[u8],
30 ) -> Result<(), InvalidSignature> {
31 if matches!(
32 self.public_key_alg_id,
33 alg_id::ECDSA_P256 | alg_id::ECDSA_P384 | alg_id::ECDSA_P521
34 ) {
35 match public_key.first() {
44 Some(0x04) | Some(0x02) | Some(0x03) => {}
45 _ => return Err(InvalidSignature),
46 };
47 }
48 signature::UnparsedPublicKey::new(self.verification_alg, public_key)
49 .verify(message, signature)
50 .map_err(|_| InvalidSignature)
51 }
52
53 fn fips(&self) -> bool {
54 self.in_fips_submission && try_fips_mode().is_ok()
55 }
56}
57
58pub static ML_DSA_44: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
60 public_key_alg_id: alg_id::ML_DSA_44,
61 signature_alg_id: alg_id::ML_DSA_44,
62 verification_alg: &signature::ML_DSA_44,
63 in_fips_submission: false,
65};
66
67pub static ML_DSA_65: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
69 public_key_alg_id: alg_id::ML_DSA_65,
70 signature_alg_id: alg_id::ML_DSA_65,
71 verification_alg: &signature::ML_DSA_65,
72 in_fips_submission: false,
74};
75
76pub static ML_DSA_87: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
78 public_key_alg_id: alg_id::ML_DSA_87,
79 signature_alg_id: alg_id::ML_DSA_87,
80 verification_alg: &signature::ML_DSA_87,
81 in_fips_submission: false,
83};
84
85pub static ECDSA_P256_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
87 public_key_alg_id: alg_id::ECDSA_P256,
88 signature_alg_id: alg_id::ECDSA_SHA256,
89 verification_alg: &signature::ECDSA_P256_SHA256_ASN1,
90 in_fips_submission: true,
91};
92
93pub static ECDSA_P256_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
95 public_key_alg_id: alg_id::ECDSA_P256,
96 signature_alg_id: alg_id::ECDSA_SHA384,
97 verification_alg: &signature::ECDSA_P256_SHA384_ASN1,
98 in_fips_submission: true,
99};
100
101pub static ECDSA_P256_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
103 public_key_alg_id: alg_id::ECDSA_P256,
104 signature_alg_id: alg_id::ECDSA_SHA512,
105 verification_alg: &signature::ECDSA_P256_SHA512_ASN1,
106 in_fips_submission: true,
107};
108
109pub static ECDSA_P384_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
111 public_key_alg_id: alg_id::ECDSA_P384,
112 signature_alg_id: alg_id::ECDSA_SHA256,
113 verification_alg: &signature::ECDSA_P384_SHA256_ASN1,
114 in_fips_submission: true,
115};
116
117pub static ECDSA_P384_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
119 public_key_alg_id: alg_id::ECDSA_P384,
120 signature_alg_id: alg_id::ECDSA_SHA384,
121 verification_alg: &signature::ECDSA_P384_SHA384_ASN1,
122 in_fips_submission: true,
123};
124
125pub static ECDSA_P384_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
127 public_key_alg_id: alg_id::ECDSA_P384,
128 signature_alg_id: alg_id::ECDSA_SHA512,
129 verification_alg: &signature::ECDSA_P384_SHA512_ASN1,
130 in_fips_submission: true,
131};
132
133pub static ECDSA_P521_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
135 public_key_alg_id: alg_id::ECDSA_P521,
136 signature_alg_id: alg_id::ECDSA_SHA256,
137 verification_alg: &signature::ECDSA_P521_SHA256_ASN1,
138 in_fips_submission: true,
139};
140
141pub static ECDSA_P521_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
143 public_key_alg_id: alg_id::ECDSA_P521,
144 signature_alg_id: alg_id::ECDSA_SHA384,
145 verification_alg: &signature::ECDSA_P521_SHA384_ASN1,
146 in_fips_submission: true,
147};
148
149pub static ECDSA_P521_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
151 public_key_alg_id: alg_id::ECDSA_P521,
152 signature_alg_id: alg_id::ECDSA_SHA512,
153 verification_alg: &signature::ECDSA_P521_SHA512_ASN1,
154 in_fips_submission: true,
155};
156
157pub static RSA_PKCS1_2048_8192_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
159 public_key_alg_id: alg_id::RSA_ENCRYPTION,
160 signature_alg_id: alg_id::RSA_PKCS1_SHA256,
161 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
162 in_fips_submission: true,
163};
164
165pub static RSA_PKCS1_2048_8192_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
167 public_key_alg_id: alg_id::RSA_ENCRYPTION,
168 signature_alg_id: alg_id::RSA_PKCS1_SHA384,
169 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
170 in_fips_submission: true,
171};
172
173pub static RSA_PKCS1_2048_8192_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
175 public_key_alg_id: alg_id::RSA_ENCRYPTION,
176 signature_alg_id: alg_id::RSA_PKCS1_SHA512,
177 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
178 in_fips_submission: true,
179};
180
181pub static RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
193 &AwsLcRsAlgorithm {
194 public_key_alg_id: alg_id::RSA_ENCRYPTION,
195 signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
196 "data/alg-rsa-pkcs1-sha256-absent-params.der"
197 )),
198 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
199 in_fips_submission: true,
200 };
201
202pub static RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
214 &AwsLcRsAlgorithm {
215 public_key_alg_id: alg_id::RSA_ENCRYPTION,
216 signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
217 "data/alg-rsa-pkcs1-sha384-absent-params.der"
218 )),
219 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
220 in_fips_submission: true,
221 };
222
223pub static RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
235 &AwsLcRsAlgorithm {
236 public_key_alg_id: alg_id::RSA_ENCRYPTION,
237 signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
238 "data/alg-rsa-pkcs1-sha512-absent-params.der"
239 )),
240 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
241 in_fips_submission: true,
242 };
243
244pub static RSA_PKCS1_3072_8192_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
246 public_key_alg_id: alg_id::RSA_ENCRYPTION,
247 signature_alg_id: alg_id::RSA_PKCS1_SHA384,
248 verification_alg: &signature::RSA_PKCS1_3072_8192_SHA384,
249 in_fips_submission: true,
250};
251
252pub static RSA_PSS_2048_8192_SHA256_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
257 &AwsLcRsAlgorithm {
258 public_key_alg_id: alg_id::RSA_ENCRYPTION,
259 signature_alg_id: alg_id::RSA_PSS_SHA256,
260 verification_alg: &signature::RSA_PSS_2048_8192_SHA256,
261 in_fips_submission: true,
262 };
263
264pub static RSA_PSS_2048_8192_SHA384_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
269 &AwsLcRsAlgorithm {
270 public_key_alg_id: alg_id::RSA_ENCRYPTION,
271 signature_alg_id: alg_id::RSA_PSS_SHA384,
272 verification_alg: &signature::RSA_PSS_2048_8192_SHA384,
273 in_fips_submission: true,
274 };
275
276pub static RSA_PSS_2048_8192_SHA512_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
281 &AwsLcRsAlgorithm {
282 public_key_alg_id: alg_id::RSA_ENCRYPTION,
283 signature_alg_id: alg_id::RSA_PSS_SHA512,
284 verification_alg: &signature::RSA_PSS_2048_8192_SHA512,
285 in_fips_submission: true,
286 };
287
288pub static ED25519: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
290 public_key_alg_id: alg_id::ED25519,
291 signature_alg_id: alg_id::ED25519,
292 verification_alg: &signature::ED25519,
293 in_fips_submission: true,
294};
295
296#[cfg(test)]
297#[path = "."]
298mod tests {
299 use crate::error::{
300 Error, UnsupportedSignatureAlgorithmContext,
301 UnsupportedSignatureAlgorithmForPublicKeyContext,
302 };
303
304 static SUPPORTED_ALGORITHMS_IN_TESTS: &[&dyn super::SignatureVerificationAlgorithm] = &[
305 super::ECDSA_P256_SHA256,
307 super::ECDSA_P384_SHA384,
308 super::ECDSA_P521_SHA256,
309 super::ECDSA_P521_SHA384,
310 super::ECDSA_P521_SHA512,
311 super::ED25519,
312 super::RSA_PKCS1_2048_8192_SHA256,
313 super::RSA_PKCS1_2048_8192_SHA384,
314 super::RSA_PKCS1_2048_8192_SHA512,
315 super::RSA_PKCS1_3072_8192_SHA384,
316 super::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
317 super::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
318 super::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
319 super::ECDSA_P256_SHA384, super::ECDSA_P384_SHA256, super::ML_DSA_44,
323 super::ML_DSA_65,
324 super::ML_DSA_87,
325 ];
326
327 const OK_IF_POINT_COMPRESSION_SUPPORTED: Result<(), Error> = Ok(());
328
329 #[path = "alg_tests.rs"]
330 mod alg_tests;
331
332 fn maybe_rsa() -> Result<(), Error> {
333 Ok(())
334 }
335
336 fn unsupported_for_rsa(_sig_alg_id: &[u8], _public_key_alg_id: &[u8]) -> Error {
337 Error::UnsupportedSignatureAlgorithmForPublicKeyContext(
338 UnsupportedSignatureAlgorithmForPublicKeyContext {
339 #[cfg(feature = "alloc")]
340 signature_algorithm_id: _sig_alg_id.to_vec(),
341 #[cfg(feature = "alloc")]
342 public_key_algorithm_id: _public_key_alg_id.to_vec(),
343 },
344 )
345 }
346
347 fn invalid_rsa_signature() -> Error {
348 Error::InvalidSignatureForPublicKey
349 }
350
351 fn unsupported_for_ecdsa(_sig_alg_id: &[u8], _public_key_alg_id: &[u8]) -> Error {
352 Error::UnsupportedSignatureAlgorithmForPublicKeyContext(
353 UnsupportedSignatureAlgorithmForPublicKeyContext {
354 #[cfg(feature = "alloc")]
355 signature_algorithm_id: _sig_alg_id.to_vec(),
356 #[cfg(feature = "alloc")]
357 public_key_algorithm_id: _public_key_alg_id.to_vec(),
358 },
359 )
360 }
361
362 fn unsupported(_sig_alg_id: &[u8]) -> Error {
363 Error::UnsupportedSignatureAlgorithmContext(UnsupportedSignatureAlgorithmContext {
364 #[cfg(feature = "alloc")]
365 signature_algorithm_id: _sig_alg_id.to_vec(),
366 #[cfg(feature = "alloc")]
367 supported_algorithms: SUPPORTED_ALGORITHMS_IN_TESTS
368 .iter()
369 .map(|&alg| alg.signature_alg_id())
370 .collect(),
371 })
372 }
373}