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}
14
15impl SignatureVerificationAlgorithm for AwsLcRsAlgorithm {
16 fn public_key_alg_id(&self) -> AlgorithmIdentifier {
17 self.public_key_alg_id
18 }
19
20 fn signature_alg_id(&self) -> AlgorithmIdentifier {
21 self.signature_alg_id
22 }
23
24 fn verify_signature(
25 &self,
26 public_key: &[u8],
27 message: &[u8],
28 signature: &[u8],
29 ) -> Result<(), InvalidSignature> {
30 if matches!(
31 self.public_key_alg_id,
32 alg_id::ECDSA_P256 | alg_id::ECDSA_P384 | alg_id::ECDSA_P521
33 ) {
34 match public_key.first() {
43 Some(0x04) | Some(0x02) | Some(0x03) => {}
44 _ => return Err(InvalidSignature),
45 };
46 }
47 signature::UnparsedPublicKey::new(self.verification_alg, public_key)
48 .verify(message, signature)
49 .map_err(|_| InvalidSignature)
50 }
51
52 fn fips(&self) -> bool {
53 try_fips_mode().is_ok()
54 }
55}
56
57pub static ML_DSA_44: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
59 public_key_alg_id: alg_id::ML_DSA_44,
60 signature_alg_id: alg_id::ML_DSA_44,
61 verification_alg: &signature::ML_DSA_44,
62};
63
64pub static ML_DSA_65: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
66 public_key_alg_id: alg_id::ML_DSA_65,
67 signature_alg_id: alg_id::ML_DSA_65,
68 verification_alg: &signature::ML_DSA_65,
69};
70
71pub static ML_DSA_87: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
73 public_key_alg_id: alg_id::ML_DSA_87,
74 signature_alg_id: alg_id::ML_DSA_87,
75 verification_alg: &signature::ML_DSA_87,
76};
77
78pub static ECDSA_P256_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
80 public_key_alg_id: alg_id::ECDSA_P256,
81 signature_alg_id: alg_id::ECDSA_SHA256,
82 verification_alg: &signature::ECDSA_P256_SHA256_ASN1,
83};
84
85pub static ECDSA_P256_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
87 public_key_alg_id: alg_id::ECDSA_P256,
88 signature_alg_id: alg_id::ECDSA_SHA384,
89 verification_alg: &signature::ECDSA_P256_SHA384_ASN1,
90};
91
92pub static ECDSA_P256_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
94 public_key_alg_id: alg_id::ECDSA_P256,
95 signature_alg_id: alg_id::ECDSA_SHA512,
96 verification_alg: &signature::ECDSA_P256_SHA512_ASN1,
97};
98
99pub static ECDSA_P384_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
101 public_key_alg_id: alg_id::ECDSA_P384,
102 signature_alg_id: alg_id::ECDSA_SHA256,
103 verification_alg: &signature::ECDSA_P384_SHA256_ASN1,
104};
105
106pub static ECDSA_P384_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
108 public_key_alg_id: alg_id::ECDSA_P384,
109 signature_alg_id: alg_id::ECDSA_SHA384,
110 verification_alg: &signature::ECDSA_P384_SHA384_ASN1,
111};
112
113pub static ECDSA_P384_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
115 public_key_alg_id: alg_id::ECDSA_P384,
116 signature_alg_id: alg_id::ECDSA_SHA512,
117 verification_alg: &signature::ECDSA_P384_SHA512_ASN1,
118};
119
120pub static ECDSA_P521_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
122 public_key_alg_id: alg_id::ECDSA_P521,
123 signature_alg_id: alg_id::ECDSA_SHA256,
124 verification_alg: &signature::ECDSA_P521_SHA256_ASN1,
125};
126
127pub static ECDSA_P521_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
129 public_key_alg_id: alg_id::ECDSA_P521,
130 signature_alg_id: alg_id::ECDSA_SHA384,
131 verification_alg: &signature::ECDSA_P521_SHA384_ASN1,
132};
133
134pub static ECDSA_P521_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
136 public_key_alg_id: alg_id::ECDSA_P521,
137 signature_alg_id: alg_id::ECDSA_SHA512,
138 verification_alg: &signature::ECDSA_P521_SHA512_ASN1,
139};
140
141pub static RSA_PKCS1_2048_8192_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
143 public_key_alg_id: alg_id::RSA_ENCRYPTION,
144 signature_alg_id: alg_id::RSA_PKCS1_SHA256,
145 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
146};
147
148pub static RSA_PKCS1_2048_8192_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
150 public_key_alg_id: alg_id::RSA_ENCRYPTION,
151 signature_alg_id: alg_id::RSA_PKCS1_SHA384,
152 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
153};
154
155pub static RSA_PKCS1_2048_8192_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
157 public_key_alg_id: alg_id::RSA_ENCRYPTION,
158 signature_alg_id: alg_id::RSA_PKCS1_SHA512,
159 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
160};
161
162pub static RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
174 &AwsLcRsAlgorithm {
175 public_key_alg_id: alg_id::RSA_ENCRYPTION,
176 signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
177 "data/alg-rsa-pkcs1-sha256-absent-params.der"
178 )),
179 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
180 };
181
182pub static RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
194 &AwsLcRsAlgorithm {
195 public_key_alg_id: alg_id::RSA_ENCRYPTION,
196 signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
197 "data/alg-rsa-pkcs1-sha384-absent-params.der"
198 )),
199 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
200 };
201
202pub static RSA_PKCS1_2048_8192_SHA512_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-sha512-absent-params.der"
218 )),
219 verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
220 };
221
222pub static RSA_PKCS1_3072_8192_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
224 public_key_alg_id: alg_id::RSA_ENCRYPTION,
225 signature_alg_id: alg_id::RSA_PKCS1_SHA384,
226 verification_alg: &signature::RSA_PKCS1_3072_8192_SHA384,
227};
228
229pub static RSA_PSS_2048_8192_SHA256_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
234 &AwsLcRsAlgorithm {
235 public_key_alg_id: alg_id::RSA_ENCRYPTION,
236 signature_alg_id: alg_id::RSA_PSS_SHA256,
237 verification_alg: &signature::RSA_PSS_2048_8192_SHA256,
238 };
239
240pub static RSA_PSS_2048_8192_SHA384_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
245 &AwsLcRsAlgorithm {
246 public_key_alg_id: alg_id::RSA_ENCRYPTION,
247 signature_alg_id: alg_id::RSA_PSS_SHA384,
248 verification_alg: &signature::RSA_PSS_2048_8192_SHA384,
249 };
250
251pub static RSA_PSS_2048_8192_SHA512_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
256 &AwsLcRsAlgorithm {
257 public_key_alg_id: alg_id::RSA_ENCRYPTION,
258 signature_alg_id: alg_id::RSA_PSS_SHA512,
259 verification_alg: &signature::RSA_PSS_2048_8192_SHA512,
260 };
261
262pub static ED25519: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
264 public_key_alg_id: alg_id::ED25519,
265 signature_alg_id: alg_id::ED25519,
266 verification_alg: &signature::ED25519,
267};
268
269#[cfg(test)]
270#[path = "."]
271mod tests {
272 use crate::error::{
273 Error, UnsupportedSignatureAlgorithmContext,
274 UnsupportedSignatureAlgorithmForPublicKeyContext,
275 };
276
277 static SUPPORTED_ALGORITHMS_IN_TESTS: &[&dyn super::SignatureVerificationAlgorithm] = &[
278 super::ECDSA_P256_SHA256,
280 super::ECDSA_P384_SHA384,
281 super::ECDSA_P521_SHA256,
282 super::ECDSA_P521_SHA384,
283 super::ECDSA_P521_SHA512,
284 super::ED25519,
285 super::RSA_PKCS1_2048_8192_SHA256,
286 super::RSA_PKCS1_2048_8192_SHA384,
287 super::RSA_PKCS1_2048_8192_SHA512,
288 super::RSA_PKCS1_3072_8192_SHA384,
289 super::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
290 super::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
291 super::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
292 super::ECDSA_P256_SHA384, super::ECDSA_P384_SHA256, super::ML_DSA_44,
296 super::ML_DSA_65,
297 super::ML_DSA_87,
298 ];
299
300 const OK_IF_POINT_COMPRESSION_SUPPORTED: Result<(), Error> = Ok(());
301
302 #[path = "alg_tests.rs"]
303 mod alg_tests;
304
305 fn maybe_rsa() -> Result<(), Error> {
306 Ok(())
307 }
308
309 fn unsupported_for_rsa(_sig_alg_id: &[u8], _public_key_alg_id: &[u8]) -> Error {
310 Error::UnsupportedSignatureAlgorithmForPublicKeyContext(
311 UnsupportedSignatureAlgorithmForPublicKeyContext {
312 #[cfg(feature = "alloc")]
313 signature_algorithm_id: _sig_alg_id.to_vec(),
314 #[cfg(feature = "alloc")]
315 public_key_algorithm_id: _public_key_alg_id.to_vec(),
316 },
317 )
318 }
319
320 fn invalid_rsa_signature() -> Error {
321 Error::InvalidSignatureForPublicKey
322 }
323
324 fn unsupported_for_ecdsa(_sig_alg_id: &[u8], _public_key_alg_id: &[u8]) -> Error {
325 Error::UnsupportedSignatureAlgorithmForPublicKeyContext(
326 UnsupportedSignatureAlgorithmForPublicKeyContext {
327 #[cfg(feature = "alloc")]
328 signature_algorithm_id: _sig_alg_id.to_vec(),
329 #[cfg(feature = "alloc")]
330 public_key_algorithm_id: _public_key_alg_id.to_vec(),
331 },
332 )
333 }
334
335 fn unsupported(_sig_alg_id: &[u8]) -> Error {
336 Error::UnsupportedSignatureAlgorithmContext(UnsupportedSignatureAlgorithmContext {
337 #[cfg(feature = "alloc")]
338 signature_algorithm_id: _sig_alg_id.to_vec(),
339 #[cfg(feature = "alloc")]
340 supported_algorithms: SUPPORTED_ALGORITHMS_IN_TESTS
341 .iter()
342 .map(|&alg| alg.signature_alg_id())
343 .collect(),
344 })
345 }
346}