1use alloc::boxed::Box;
2
3use constant_time_eq::constant_time_eq;
4use crypto::{
5 Hash, Hasher,
6 blake3::Blake3,
7 curve25519::ed25519,
8 hmac::Hmac,
9 mldsa::{
10 ML_DSA_44_SIGNATURE_SIZE, ML_DSA_65_SIGNATURE_SIZE, ML_DSA_87_SIGNATURE_SIZE, MlDsa44PublicKey,
11 MlDsa44SecretKey, MlDsa65PublicKey, MlDsa65SecretKey, MlDsa87PublicKey, MlDsa87SecretKey,
12 },
13 p256, p384, p521, rsa,
14 sha2::{Sha256, Sha384, Sha512},
15};
16
17use crate::{Algorithm, EcCurve, Error, Jwk, JwkCrypto, OkpCurve};
18
19pub(crate) const SIGNATURE_MAX_SIZE: usize = 4627; pub trait Signer {
22 fn sign(&self, message: &[u8]) -> Result<Signature, Error>;
23 fn algorithm(&self) -> Algorithm;
24}
25
26pub trait Verifier {
27 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error>;
28 fn algorithm(&self) -> Algorithm;
29}
30
31#[derive(Clone, Copy)]
36pub struct Signature {
37 value: [u8; SIGNATURE_MAX_SIZE],
38 length: usize,
39}
40
41impl core::ops::Deref for Signature {
42 type Target = [u8];
43
44 #[inline]
45 fn deref(&self) -> &[u8] {
46 &self.value[..self.length as usize]
47 }
48}
49
50impl AsRef<[u8]> for Signature {
51 #[inline]
52 fn as_ref(&self) -> &[u8] {
53 &self.value[..self.length]
54 }
55}
56
57impl TryFrom<&[u8]> for Signature {
58 type Error = Error;
59
60 #[inline]
61 fn try_from(signature: &[u8]) -> Result<Self, Self::Error> {
62 let length = signature.len();
63 if length > SIGNATURE_MAX_SIZE {
64 return Err(Error::InvalidSignature);
65 }
66
67 let mut value = [0u8; SIGNATURE_MAX_SIZE];
68 value[..length].copy_from_slice(signature);
69
70 return Ok(Signature {
71 value,
72 length,
73 });
74 }
75}
76
77impl<const N: usize> TryFrom<[u8; N]> for Signature {
78 type Error = Error;
79
80 #[inline]
81 fn try_from(signature: [u8; N]) -> Result<Self, Self::Error> {
82 signature.as_slice().try_into()
83 }
84}
85
86impl<const N: usize> TryFrom<&[u8; N]> for Signature {
87 type Error = Error;
88
89 #[inline]
90 fn try_from(signature: &[u8; N]) -> Result<Self, Self::Error> {
91 signature.as_slice().try_into()
92 }
93}
94
95#[allow(clippy::large_enum_variant)] pub enum Key<'a> {
121 Secret(SecretKey<'a>),
123
124 Ed25519Public(ed25519::PublicKey),
126
127 Ed25519Secret(ed25519::SecretKey),
129
130 P256Public(p256::PublicKey),
132
133 P256Secret(p256::SecretKey),
135
136 P384Public(p384::PublicKey),
138
139 P521Public(p521::PublicKey),
141
142 P521Secret(p521::SecretKey),
144
145 Rsa(RsaPublicKey),
147
148 MlDsa44Public(MlDsa44PublicKey),
150
151 MlDsa44Secret(MlDsa44SecretKey),
153
154 MlDsa65Public(MlDsa65PublicKey),
156
157 MlDsa65Secret(Box<MlDsa65SecretKey>),
162
163 MlDsa87Public(MlDsa87PublicKey),
165
166 MlDsa87Secret(Box<MlDsa87SecretKey>),
171}
172
173impl<'a> TryFrom<&'a Jwk> for Key<'a> {
174 type Error = Error;
175
176 fn try_from(jwk: &'a Jwk) -> Result<Self, Self::Error> {
177 match &jwk.crypto {
178 JwkCrypto::Oct {
179 ..
180 } => Ok(Key::Secret(SecretKey::try_from(jwk)?)),
181 JwkCrypto::Okp {
182 curve: OkpCurve::Ed25519,
183 d: Some(_),
184 ..
185 } => Ok(Key::Ed25519Secret(ed25519::SecretKey::try_from(jwk)?)),
186 JwkCrypto::Okp {
187 curve: OkpCurve::Ed25519,
188 ..
189 } => Ok(Key::Ed25519Public(ed25519::PublicKey::try_from(jwk)?)),
190 JwkCrypto::Ec {
191 curve: EcCurve::P256,
192 d: Some(_),
193 ..
194 } => Ok(Key::P256Secret(p256::SecretKey::try_from(jwk)?)),
195 JwkCrypto::Ec {
196 curve: EcCurve::P256, ..
197 } => Ok(Key::P256Public(p256::PublicKey::try_from(jwk)?)),
198 JwkCrypto::Ec {
199 curve: EcCurve::P384, ..
200 } => Ok(Key::P384Public(p384::PublicKey::try_from(jwk)?)),
201 JwkCrypto::Ec {
202 curve: EcCurve::P521,
203 d: Some(_),
204 ..
205 } => Ok(Key::P521Secret(p521::SecretKey::try_from(jwk)?)),
206 JwkCrypto::Ec {
207 curve: EcCurve::P521, ..
208 } => Ok(Key::P521Public(p521::PublicKey::try_from(jwk)?)),
209 JwkCrypto::Rsa {
210 ..
211 } => Ok(Key::Rsa(RsaPublicKey::try_from(jwk)?)),
212 JwkCrypto::Akp {
213 private_key: Some(_), ..
214 } => match jwk.algorithm {
215 Algorithm::MlDsa44 => Ok(Key::MlDsa44Secret(MlDsa44SecretKey::try_from(jwk)?)),
216 Algorithm::MlDsa65 => Ok(Key::MlDsa65Secret(alloc::boxed::Box::new(MlDsa65SecretKey::try_from(jwk)?))),
217 Algorithm::MlDsa87 => Ok(Key::MlDsa87Secret(alloc::boxed::Box::new(MlDsa87SecretKey::try_from(jwk)?))),
218 _ => Err(Error::InvalidKey),
219 },
220 JwkCrypto::Akp {
221 private_key: None, ..
222 } => match jwk.algorithm {
223 Algorithm::MlDsa44 => Ok(Key::MlDsa44Public(MlDsa44PublicKey::try_from(jwk)?)),
224 Algorithm::MlDsa65 => Ok(Key::MlDsa65Public(MlDsa65PublicKey::try_from(jwk)?)),
225 Algorithm::MlDsa87 => Ok(Key::MlDsa87Public(MlDsa87PublicKey::try_from(jwk)?)),
226 _ => Err(Error::InvalidKey),
227 },
228 }
229 }
230}
231
232impl Key<'_> {
233 fn jose_algorithm(&self) -> Algorithm {
235 match self {
236 Key::Secret(key) => Signer::algorithm(key),
237 Key::Ed25519Public(_) | Key::Ed25519Secret(_) => Algorithm::EdDSA,
238 Key::P256Public(_) | Key::P256Secret(_) => Algorithm::ES256,
239 Key::P384Public(_) => Algorithm::ES384,
240 Key::P521Public(_) | Key::P521Secret(_) => Algorithm::ES512,
241 Key::Rsa(key) => Verifier::algorithm(key),
242 Key::MlDsa44Public(_) | Key::MlDsa44Secret(_) => Algorithm::MlDsa44,
243 Key::MlDsa65Public(_) | Key::MlDsa65Secret(_) => Algorithm::MlDsa65,
244 Key::MlDsa87Public(_) | Key::MlDsa87Secret(_) => Algorithm::MlDsa87,
245 }
246 }
247
248 pub fn is_secret_key(&self) -> bool {
250 match self {
251 Key::Secret(_)
252 | Key::Ed25519Secret(_)
253 | Key::P256Secret(_)
254 | Key::P521Secret(_)
255 | Key::MlDsa44Secret(_)
256 | Key::MlDsa65Secret(_)
257 | Key::MlDsa87Secret(_) => true,
258 _ => false,
259 }
260 }
261}
262
263impl Signer for Key<'_> {
264 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
265 match self {
266 Key::Secret(key) => Signer::sign(key, message),
267 Key::Ed25519Secret(key) => Signer::sign(key, message),
268 Key::P256Secret(key) => Signer::sign(key, message),
269 Key::P521Secret(key) => Signer::sign(key, message),
270 Key::MlDsa44Secret(key) => Signer::sign(key, message),
271 Key::MlDsa65Secret(key) => Signer::sign(key.as_ref(), message),
272 Key::MlDsa87Secret(key) => Signer::sign(key.as_ref(), message),
273 _ => Err(Error::InvalidKey),
274 }
275 }
276
277 #[inline(always)]
278 fn algorithm(&self) -> Algorithm {
279 self.jose_algorithm()
280 }
281}
282
283impl Verifier for Key<'_> {
284 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
285 match self {
286 Key::Secret(key) => Verifier::verify(key, message, signature),
287 Key::Ed25519Public(key) => Verifier::verify(key, message, signature),
288 Key::Ed25519Secret(key) => Verifier::verify(&key.public_key(), message, signature),
289 Key::P256Public(key) => Verifier::verify(key, message, signature),
290 Key::P256Secret(key) => Verifier::verify(&key.public_key(), message, signature),
291 Key::P384Public(key) => Verifier::verify(key, message, signature),
292 Key::P521Public(key) => Verifier::verify(key, message, signature),
293 Key::P521Secret(key) => Verifier::verify(&key.public_key(), message, signature),
294 Key::Rsa(key) => Verifier::verify(key, message, signature),
295 Key::MlDsa44Public(key) => Verifier::verify(key, message, signature),
296 Key::MlDsa44Secret(key) => Verifier::verify(&key.public_key(), message, signature),
297 Key::MlDsa65Public(key) => Verifier::verify(key, message, signature),
298 Key::MlDsa65Secret(key) => Verifier::verify(&key.public_key(), message, signature),
299 Key::MlDsa87Public(key) => Verifier::verify(key, message, signature),
300 Key::MlDsa87Secret(key) => Verifier::verify(&key.public_key(), message, signature),
301 }
302 }
303
304 #[inline(always)]
305 fn algorithm(&self) -> Algorithm {
306 self.jose_algorithm()
307 }
308}
309
310impl core::fmt::Debug for Key<'_> {
311 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
312 f.write_str(match self {
313 Key::Secret(_) => "Key::Secret",
314 Key::Ed25519Public(_) => "Key::Ed25519Public",
315 Key::Ed25519Secret(_) => "Key::Ed25519Secret",
316 Key::P256Public(_) => "Key::P256Public",
317 Key::P256Secret(_) => "Key::P256Secret",
318 Key::P384Public(_) => "Key::P384Public",
319 Key::P521Public(_) => "Key::P521Public",
320 Key::P521Secret(_) => "Key::P521Secret",
321 Key::Rsa(_) => "Key::Rsa",
322 Key::MlDsa44Public(_) => "Key::MlDsa44Public",
323 Key::MlDsa44Secret(_) => "Key::MlDsa44Secret",
324 Key::MlDsa65Public(_) => "Key::MlDsa65Public",
325 Key::MlDsa65Secret(_) => "Key::MlDsa65Secret",
326 Key::MlDsa87Public(_) => "Key::MlDsa87Public",
327 Key::MlDsa87Secret(_) => "Key::MlDsa87Secret",
328 })
329 }
330}
331
332pub struct SecretKey<'a> {
344 pub(crate) key: &'a [u8],
345 pub(crate) algorithm: Algorithm,
346}
347
348impl<'a> SecretKey<'a> {
349 #[inline(always)]
351 pub fn new(algorithm: Algorithm, key: &'a [u8]) -> Self {
352 Self {
353 key,
354 algorithm,
355 }
356 }
357
358 fn mac(&self, message: &[u8]) -> Result<Hash, Error> {
360 match self.algorithm {
361 Algorithm::BLAKE3 => {
362 let key: &[u8; 32] = self.key.try_into().map_err(|_| Error::InvalidKey)?;
363 Ok(Blake3::keyed_hash(key, message))
364 }
365 Algorithm::HS256 => self.hmac::<Sha256>(message),
366 Algorithm::HS384 => self.hmac::<Sha384>(message),
367 Algorithm::HS512 => self.hmac::<Sha512>(message),
368 _ => Err(Error::InvalidKey),
369 }
370 }
371
372 fn hmac<H: Hasher>(&self, message: &[u8]) -> Result<Hash, Error> {
374 if self.key.len() < 16 {
375 return Err(Error::InvalidKey);
376 }
377
378 Ok(Hmac::<H>::mac(self.key, message))
379 }
380}
381
382impl Signer for SecretKey<'_> {
383 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
384 return self.mac(message)?.as_ref().try_into();
385 }
386
387 #[inline(always)]
388 fn algorithm(&self) -> Algorithm {
389 self.algorithm
390 }
391}
392
393impl Verifier for SecretKey<'_> {
394 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
395 let mac = self.mac(message)?;
396 return match constant_time_eq(mac.as_ref(), signature) {
397 true => Ok(()),
398 false => Err(Error::InvalidSignature),
399 };
400 }
401
402 #[inline(always)]
403 fn algorithm(&self) -> Algorithm {
404 self.algorithm
405 }
406}
407
408impl Signer for ed25519::SecretKey {
413 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
414 return ed25519::SecretKey::sign(self, message).as_ref().try_into();
415 }
416
417 #[inline(always)]
418 fn algorithm(&self) -> Algorithm {
419 Algorithm::EdDSA
420 }
421}
422
423impl Verifier for ed25519::PublicKey {
424 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
425 let signature = signature.try_into().map_err(|_| Error::InvalidSignature)?;
426 return ed25519::PublicKey::verify(self, message, &signature).map_err(|_| Error::InvalidSignature);
427 }
428
429 #[inline(always)]
430 fn algorithm(&self) -> Algorithm {
431 Algorithm::EdDSA
432 }
433}
434
435impl Signer for p256::SecretKey {
440 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
441 return p256::SecretKey::sign(self, message)
442 .map_err(|err| Error::Unspecified(alloc::format!("error signing message: {err:?}")))?
443 .as_ref()
444 .try_into();
445 }
446
447 #[inline(always)]
448 fn algorithm(&self) -> Algorithm {
449 Algorithm::ES256
450 }
451}
452
453impl Verifier for p256::PublicKey {
454 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
455 let signature = signature.try_into().map_err(|_| Error::InvalidSignature)?;
456 return p256::PublicKey::verify(self, message, &signature).map_err(|_| Error::InvalidSignature);
457 }
458
459 #[inline(always)]
460 fn algorithm(&self) -> Algorithm {
461 Algorithm::ES256
462 }
463}
464
465impl Verifier for p384::PublicKey {
470 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
471 let signature = signature.try_into().map_err(|_| Error::InvalidSignature)?;
472 return p384::PublicKey::verify(self, message, &signature).map_err(|_| Error::InvalidSignature);
473 }
474
475 #[inline(always)]
476 fn algorithm(&self) -> Algorithm {
477 Algorithm::ES384
478 }
479}
480
481impl Signer for p521::SecretKey {
486 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
487 return p521::SecretKey::sign(self, message)
488 .map_err(|err| Error::Unspecified(alloc::format!("error signing message: {err:?}")))?
489 .as_ref()
490 .try_into();
491 }
492
493 #[inline(always)]
494 fn algorithm(&self) -> Algorithm {
495 Algorithm::ES512
496 }
497}
498
499impl Verifier for p521::PublicKey {
500 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
501 let signature = signature.try_into().map_err(|_| Error::InvalidSignature)?;
502 return p521::PublicKey::verify(self, message, &signature).map_err(|_| Error::InvalidSignature);
503 }
504
505 #[inline(always)]
506 fn algorithm(&self) -> Algorithm {
507 Algorithm::ES512
508 }
509}
510
511impl Signer for MlDsa44SecretKey {
516 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
517 return MlDsa44SecretKey::sign(self, message, b"")
518 .map_err(|_| Error::InvalidSignature)?
519 .as_ref()
520 .try_into();
521 }
522
523 #[inline(always)]
524 fn algorithm(&self) -> Algorithm {
525 Algorithm::MlDsa44
526 }
527}
528
529impl Verifier for MlDsa44PublicKey {
530 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
531 let signature: &[u8; ML_DSA_44_SIGNATURE_SIZE] = signature.try_into().map_err(|_| Error::InvalidSignature)?;
532 return MlDsa44PublicKey::verify(self, message, signature, b"").map_err(|_| Error::InvalidSignature);
533 }
534
535 #[inline(always)]
536 fn algorithm(&self) -> Algorithm {
537 Algorithm::MlDsa44
538 }
539}
540
541impl Signer for MlDsa65SecretKey {
546 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
547 return MlDsa65SecretKey::sign(self, message, b"")
548 .map_err(|_| Error::InvalidSignature)?
549 .as_ref()
550 .try_into();
551 }
552
553 #[inline(always)]
554 fn algorithm(&self) -> Algorithm {
555 Algorithm::MlDsa65
556 }
557}
558
559impl Verifier for MlDsa65PublicKey {
560 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
561 let signature: &[u8; ML_DSA_65_SIGNATURE_SIZE] = signature.try_into().map_err(|_| Error::InvalidSignature)?;
562 return MlDsa65PublicKey::verify(self, message, signature, b"").map_err(|_| Error::InvalidSignature);
563 }
564
565 #[inline(always)]
566 fn algorithm(&self) -> Algorithm {
567 Algorithm::MlDsa65
568 }
569}
570
571impl Signer for MlDsa87SecretKey {
576 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
577 return MlDsa87SecretKey::sign(self, message, b"")
578 .map_err(|_| Error::InvalidSignature)?
579 .as_ref()
580 .try_into();
581 }
582
583 #[inline(always)]
584 fn algorithm(&self) -> Algorithm {
585 Algorithm::MlDsa87
586 }
587}
588
589impl Verifier for MlDsa87PublicKey {
590 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
591 let signature: &[u8; ML_DSA_87_SIGNATURE_SIZE] = signature.try_into().map_err(|_| Error::InvalidSignature)?;
592 return MlDsa87PublicKey::verify(self, message, signature, b"").map_err(|_| Error::InvalidSignature);
593 }
594
595 #[inline(always)]
596 fn algorithm(&self) -> Algorithm {
597 Algorithm::MlDsa87
598 }
599}
600
601pub struct RsaPublicKey {
634 pub(crate) key: rsa::PublicKey,
635 pub(crate) alg: Algorithm,
636}
637
638impl RsaPublicKey {
639 pub(crate) fn from_n_e(alg: Algorithm, n: &[u8], e: &[u8]) -> Result<Self, Error> {
650 if !matches!(
651 alg,
652 Algorithm::RS256
653 | Algorithm::RS384
654 | Algorithm::RS512
655 | Algorithm::PS256
656 | Algorithm::PS384
657 | Algorithm::PS512
658 ) {
659 return Err(Error::InvalidKey);
660 }
661 let key = rsa::PublicKey::from_n_e(n, e).map_err(|_| Error::InvalidKey)?;
662 Ok(RsaPublicKey {
663 key,
664 alg,
665 })
666 }
667
668 pub fn from_pkcs1_der(pkcs1_der: &[u8], alg: Algorithm) -> Result<Self, Error> {
678 if !matches!(
679 alg,
680 Algorithm::RS256
681 | Algorithm::RS384
682 | Algorithm::RS512
683 | Algorithm::PS256
684 | Algorithm::PS384
685 | Algorithm::PS512
686 ) {
687 return Err(Error::InvalidKey);
688 }
689 let key = rsa::PublicKey::from_pkcs1_der(pkcs1_der).map_err(|_| Error::InvalidKey)?;
690 Ok(RsaPublicKey {
691 key,
692 alg,
693 })
694 }
695}
696
697impl Verifier for RsaPublicKey {
698 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
699 match self.alg {
700 Algorithm::RS256 => {
701 let digest = Sha256::hash(message);
702 self.key
703 .verify_pkcs1_v1_5(signature, digest.as_ref(), rsa::DIGEST_INFO_SHA256_PREFIX)
704 }
705 Algorithm::RS384 => {
706 let digest = Sha384::hash(message);
707 self.key
708 .verify_pkcs1_v1_5(signature, digest.as_ref(), rsa::DIGEST_INFO_SHA384_PREFIX)
709 }
710 Algorithm::RS512 => {
711 let digest = Sha512::hash(message);
712 self.key
713 .verify_pkcs1_v1_5(signature, digest.as_ref(), rsa::DIGEST_INFO_SHA512_PREFIX)
714 }
715 Algorithm::PS256 => self.key.verify_pss::<Sha256>(signature, message, Sha256::OUTPUT_SIZE),
716 Algorithm::PS384 => self.key.verify_pss::<Sha384>(signature, message, Sha384::OUTPUT_SIZE),
717 Algorithm::PS512 => self.key.verify_pss::<Sha512>(signature, message, Sha512::OUTPUT_SIZE),
718 _ => return Err(Error::InvalidKey),
719 }
720 .map_err(|_| Error::InvalidSignature)
721 }
722
723 #[inline(always)]
724 fn algorithm(&self) -> Algorithm {
725 self.alg
726 }
727}