@@ -4,105 +4,143 @@ use crate::error::Error;
4
4
use crate :: error:: Result ;
5
5
use crate :: WrapperErrorKind ;
6
6
use crate :: {
7
+ abstraction:: public:: AssociatedTpmCurve ,
7
8
interface_types:: algorithm:: HashingAlgorithm ,
8
- structures:: { Attest , AttestInfo , DigestList , PcrSelectionList , Public , QuoteInfo , Signature } ,
9
+ structures:: {
10
+ Attest , AttestInfo , DigestList , EccSignature , PcrSelectionList , Public , QuoteInfo ,
11
+ Signature ,
12
+ } ,
9
13
traits:: Marshall ,
10
- utils:: PublicKey ,
11
14
} ;
12
15
use digest:: { Digest , DynDigest } ;
13
16
14
- #[ cfg( feature = "p256" ) ]
15
- use crate :: structures:: EccSignature ;
16
- #[ cfg( feature = "p256" ) ]
17
- use p256:: ecdsa:: { Signature as SignatureP256 , VerifyingKey } ;
18
- #[ cfg( feature = "p256" ) ]
17
+ use ecdsa:: {
18
+ hazmat:: { DigestPrimitive , VerifyPrimitive } ,
19
+ PrimeCurve , SignatureSize , VerifyingKey ,
20
+ } ;
21
+ use elliptic_curve:: {
22
+ generic_array:: ArrayLength ,
23
+ point:: AffinePoint ,
24
+ sec1:: { FromEncodedPoint , ModulusSize , ToEncodedPoint } ,
25
+ CurveArithmetic , FieldBytesSize ,
26
+ } ;
19
27
use signature:: { hazmat:: PrehashVerifier , Verifier } ;
20
28
21
29
#[ cfg( feature = "rsa" ) ]
22
- use crate :: structures:: RsaSignature ;
23
- #[ cfg( feature = "rsa" ) ]
24
- use rsa:: { pss:: Pss , RsaPublicKey } ;
30
+ use rsa:: { pkcs1v15, pss, RsaPublicKey } ;
25
31
26
- #[ cfg( feature = "p256" ) ]
27
- fn verify_p256 ( public : & Public , message : & [ u8 ] , signature : & EccSignature ) -> Result < bool > {
28
- let public_key = PublicKey :: try_from ( public. clone ( ) ) ?;
29
- let ( x, y) = match public_key {
30
- PublicKey :: Ecc { x, y } => ( x, y) ,
31
- _ => {
32
- return Err ( Error :: WrapperError ( WrapperErrorKind :: InvalidParam ) ) ;
33
- }
32
+ fn verify_ecdsa < C > (
33
+ public : & Public ,
34
+ message : & [ u8 ] ,
35
+ signature : & EccSignature ,
36
+ hashing_algorithm : HashingAlgorithm ,
37
+ ) -> Result < bool >
38
+ where
39
+ C : PrimeCurve + CurveArithmetic + DigestPrimitive + AssociatedTpmCurve ,
40
+ AffinePoint < C > : VerifyPrimitive < C > + FromEncodedPoint < C > + ToEncodedPoint < C > ,
41
+ SignatureSize < C > : ArrayLength < u8 > ,
42
+ FieldBytesSize < C > : ModulusSize ,
43
+ {
44
+ let Ok ( signature) = ecdsa:: Signature :: < C > :: try_from ( signature. clone ( ) ) else {
45
+ return Ok ( false ) ;
34
46
} ;
35
- let mut sec1_bytes = Vec :: < u8 > :: with_capacity ( 1 + x. len ( ) + y. len ( ) ) ;
36
- sec1_bytes. push ( 0x04 ) ;
37
- sec1_bytes. extend_from_slice ( & x) ;
38
- sec1_bytes. extend_from_slice ( & y) ;
39
- let verifying_key = match VerifyingKey :: from_sec1_bytes ( & sec1_bytes) {
40
- Ok ( s) => s,
41
- Err ( _) => {
42
- return Err ( Error :: WrapperError ( WrapperErrorKind :: InvalidParam ) ) ;
43
- }
47
+ let Ok ( public) = elliptic_curve:: PublicKey :: < C > :: try_from ( public) else {
48
+ return Ok ( false ) ;
44
49
} ;
45
50
46
- let mut sig_bytes = Vec :: with_capacity ( 64 ) ;
47
- sig_bytes. extend_from_slice ( signature. signature_r ( ) . as_ref ( ) ) ;
48
- sig_bytes. extend_from_slice ( signature. signature_s ( ) . as_ref ( ) ) ;
49
- let generic_sig = digest:: generic_array:: GenericArray :: clone_from_slice ( & sig_bytes) ;
50
- let sig = match SignatureP256 :: from_bytes ( & generic_sig) {
51
- Ok ( s) => s,
52
- Err ( _) => {
53
- return Err ( Error :: WrapperError ( WrapperErrorKind :: InvalidParam ) ) ;
54
- }
55
- } ;
51
+ let verifying_key = VerifyingKey :: from ( public) ;
56
52
57
- let verify_result = match signature . hashing_algorithm ( ) {
53
+ match hashing_algorithm {
58
54
#[ cfg( feature = "sha1" ) ]
59
55
HashingAlgorithm :: Sha1 => {
60
- let mut hasher = sha1:: Sha1 :: new ( ) ;
61
- Digest :: update ( & mut hasher, & message) ;
62
- verifying_key. verify_prehash ( & hasher. finalize ( ) , & sig)
56
+ let hash = sha1:: Sha1 :: digest ( message) ;
57
+ Ok ( verifying_key. verify_prehash ( & hash, & signature) . is_ok ( ) )
63
58
}
64
59
#[ cfg( feature = "sha2" ) ]
65
- HashingAlgorithm :: Sha256 => verifying_key . verify ( & message , & sig ) ,
66
- _ => {
67
- return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
60
+ HashingAlgorithm :: Sha256 => {
61
+ let hash = sha2 :: Sha256 :: digest ( message ) ;
62
+ Ok ( verifying_key . verify_prehash ( & hash , & signature ) . is_ok ( ) )
68
63
}
69
- } ;
70
- return Ok ( match verify_result {
71
- Ok ( _) => true ,
72
- Err ( _) => false ,
73
- } ) ;
64
+ #[ cfg( feature = "sha2" ) ]
65
+ HashingAlgorithm :: Sha384 => {
66
+ let hash = sha2:: Sha384 :: digest ( message) ;
67
+ Ok ( verifying_key. verify_prehash ( & hash, & signature) . is_ok ( ) )
68
+ }
69
+ #[ cfg( feature = "sha2" ) ]
70
+ HashingAlgorithm :: Sha512 => {
71
+ let hash = sha2:: Sha512 :: digest ( message) ;
72
+ Ok ( verifying_key. verify_prehash ( & hash, & signature) . is_ok ( ) )
73
+ }
74
+ _ => Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ,
75
+ }
74
76
}
75
77
76
78
#[ cfg( feature = "rsa" ) ]
77
- fn verify_rsa ( public : & Public , message : & [ u8 ] , signature : & RsaSignature ) -> Result < bool > {
78
- let public_key = PublicKey :: try_from ( public. clone ( ) ) ?;
79
- let rsa_key = RsaPublicKey :: try_from ( & public_key) ?;
80
- let sig = signature. signature ( ) ;
81
- let mut hasher: Box < dyn DynDigest > = match signature. hashing_algorithm ( ) {
79
+ fn verify_rsa_pss (
80
+ public : & Public ,
81
+ message : & [ u8 ] ,
82
+ signature : & pss:: Signature ,
83
+ hashing_algorithm : HashingAlgorithm ,
84
+ ) -> Result < bool > {
85
+ let rsa_key = RsaPublicKey :: try_from ( public) ?;
86
+
87
+ match hashing_algorithm {
82
88
#[ cfg( feature = "sha1" ) ]
83
- HashingAlgorithm :: Sha1 => Box :: new ( sha1:: Sha1 :: new ( ) ) ,
89
+ HashingAlgorithm :: Sha1 => {
90
+ let verifying_key = pss:: VerifyingKey :: < sha1:: Sha1 > :: from ( rsa_key) ;
91
+ Ok ( verifying_key. verify ( message, signature) . is_ok ( ) )
92
+ }
84
93
#[ cfg( feature = "sha2" ) ]
85
- HashingAlgorithm :: Sha256 => Box :: new ( sha2 :: Sha256 :: new ( ) ) ,
86
- _ => {
87
- return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
94
+ HashingAlgorithm :: Sha256 => {
95
+ let verifying_key = pss :: VerifyingKey :: < sha2 :: Sha256 > :: from ( rsa_key ) ;
96
+ Ok ( verifying_key . verify ( message , signature ) . is_ok ( ) )
88
97
}
89
- } ;
90
- hasher. update ( & message) ;
91
- let hash = hasher. finalize ( ) . to_vec ( ) ;
98
+ #[ cfg( feature = "sha2" ) ]
99
+ HashingAlgorithm :: Sha384 => {
100
+ let verifying_key = pss:: VerifyingKey :: < sha2:: Sha384 > :: from ( rsa_key) ;
101
+ Ok ( verifying_key. verify ( message, signature) . is_ok ( ) )
102
+ }
103
+ #[ cfg( feature = "sha2" ) ]
104
+ HashingAlgorithm :: Sha512 => {
105
+ let verifying_key = pss:: VerifyingKey :: < sha2:: Sha512 > :: from ( rsa_key) ;
106
+ Ok ( verifying_key. verify ( message, signature) . is_ok ( ) )
107
+ }
108
+ _ => Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ,
109
+ }
110
+ }
111
+
112
+ #[ cfg( feature = "rsa" ) ]
113
+ fn verify_rsa_pkcs1v15 (
114
+ public : & Public ,
115
+ message : & [ u8 ] ,
116
+ signature : & pkcs1v15:: Signature ,
117
+ hashing_algorithm : HashingAlgorithm ,
118
+ ) -> Result < bool > {
119
+ let rsa_key = RsaPublicKey :: try_from ( public) ?;
92
120
93
- let scheme = match signature . hashing_algorithm ( ) {
121
+ match hashing_algorithm {
94
122
#[ cfg( feature = "sha1" ) ]
95
- HashingAlgorithm :: Sha1 => Pss :: new :: < sha1:: Sha1 > ( ) ,
123
+ HashingAlgorithm :: Sha1 => {
124
+ let verifying_key = pkcs1v15:: VerifyingKey :: < sha1:: Sha1 > :: new ( rsa_key) ;
125
+ Ok ( verifying_key. verify ( message, signature) . is_ok ( ) )
126
+ }
96
127
#[ cfg( feature = "sha2" ) ]
97
- HashingAlgorithm :: Sha256 => Pss :: new :: < sha2 :: Sha256 > ( ) ,
98
- _ => {
99
- return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
128
+ HashingAlgorithm :: Sha256 => {
129
+ let verifying_key = pkcs1v15 :: VerifyingKey :: < sha2 :: Sha256 > :: new ( rsa_key ) ;
130
+ Ok ( verifying_key . verify ( message , signature ) . is_ok ( ) )
100
131
}
101
- } ;
102
- return Ok ( match rsa_key. verify ( scheme, & hash, & sig) {
103
- Ok ( _) => true ,
104
- Err ( _) => false ,
105
- } ) ;
132
+ #[ cfg( feature = "sha2" ) ]
133
+ HashingAlgorithm :: Sha384 => {
134
+ let verifying_key = pkcs1v15:: VerifyingKey :: < sha2:: Sha384 > :: new ( rsa_key) ;
135
+ Ok ( verifying_key. verify ( message, signature) . is_ok ( ) )
136
+ }
137
+ #[ cfg( feature = "sha2" ) ]
138
+ HashingAlgorithm :: Sha512 => {
139
+ let verifying_key = pkcs1v15:: VerifyingKey :: < sha2:: Sha512 > :: new ( rsa_key) ;
140
+ Ok ( verifying_key. verify ( message, signature) . is_ok ( ) )
141
+ }
142
+ _ => Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ,
143
+ }
106
144
}
107
145
108
146
fn checkquote_pcr_digests (
@@ -121,6 +159,10 @@ fn checkquote_pcr_digests(
121
159
HashingAlgorithm :: Sha1 => Box :: new ( sha1:: Sha1 :: new ( ) ) ,
122
160
#[ cfg( feature = "sha2" ) ]
123
161
HashingAlgorithm :: Sha256 => Box :: new ( sha2:: Sha256 :: new ( ) ) ,
162
+ #[ cfg( feature = "sha2" ) ]
163
+ HashingAlgorithm :: Sha384 => Box :: new ( sha2:: Sha384 :: new ( ) ) ,
164
+ #[ cfg( feature = "sha2" ) ]
165
+ HashingAlgorithm :: Sha512 => Box :: new ( sha2:: Sha512 :: new ( ) ) ,
124
166
_ => {
125
167
return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
126
168
}
@@ -265,26 +307,71 @@ pub fn checkquote(
265
307
return Err ( Error :: WrapperError ( WrapperErrorKind :: InvalidParam ) ) ;
266
308
}
267
309
} ;
310
+
268
311
let bytes = attest. marshall ( ) ?;
269
- let hash_alg = match signature {
270
- #[ cfg( feature = "p256" ) ]
271
- Signature :: EcDsa ( sig) => {
272
- if !verify_p256 ( & public, & bytes, & sig) ? {
312
+
313
+ let mut hash_alg = None ;
314
+ match ( public, signature) {
315
+ ( Public :: Ecc { parameters, .. } , _) => {
316
+ macro_rules! impl_check_ecdsa {
317
+ ( $curve: ty) => {
318
+ if parameters. ecc_curve( ) == <$curve>:: TPM_CURVE {
319
+ let Signature :: EcDsa ( sig) = signature else {
320
+ return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
321
+ } ;
322
+ if !verify_ecdsa:: <$curve>( & public, & bytes, & sig, sig. hashing_algorithm( ) ) ?
323
+ {
324
+ return Ok ( false ) ;
325
+ }
326
+
327
+ hash_alg = Some ( sig. hashing_algorithm( ) ) ;
328
+ }
329
+ } ;
330
+ }
331
+
332
+ //#[cfg(feature = "p192")]
333
+ //impl_check_ecdsa!(p192::NistP192);
334
+ #[ cfg( feature = "p224" ) ]
335
+ impl_check_ecdsa ! ( p224:: NistP224 ) ;
336
+ #[ cfg( feature = "p256" ) ]
337
+ impl_check_ecdsa ! ( p256:: NistP256 ) ;
338
+ #[ cfg( feature = "p384" ) ]
339
+ impl_check_ecdsa ! ( p384:: NistP384 ) ;
340
+ //#[cfg(feature = "p521")]
341
+ //impl_check_ecdsa!(p521::NistP521);
342
+ //#[cfg(feature = "sm2")]
343
+ //impl_check_ecdsa!(sm2::Sm2);
344
+ }
345
+ #[ cfg( feature = "rsa" ) ]
346
+ ( Public :: Rsa { .. } , sig @ Signature :: RsaSsa ( pkcs_sig) ) => {
347
+ let Ok ( sig) = pkcs1v15:: Signature :: try_from ( sig. clone ( ) ) else {
348
+ return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
349
+ } ;
350
+
351
+ if !verify_rsa_pkcs1v15 ( public, & bytes, & sig, pkcs_sig. hashing_algorithm ( ) ) ? {
273
352
return Ok ( false ) ;
274
353
}
275
- sig . hashing_algorithm ( )
354
+ hash_alg = Some ( pkcs_sig . hashing_algorithm ( ) ) ;
276
355
}
277
356
#[ cfg( feature = "rsa" ) ]
278
- Signature :: RsaPss ( sig) => {
279
- if !verify_rsa ( & public, & bytes, & sig) ? {
357
+ ( Public :: Rsa { .. } , sig @ Signature :: RsaPss ( pkcs_sig) ) => {
358
+ let Ok ( sig) = pss:: Signature :: try_from ( sig. clone ( ) ) else {
359
+ return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
360
+ } ;
361
+
362
+ if !verify_rsa_pss ( public, & bytes, & sig, pkcs_sig. hashing_algorithm ( ) ) ? {
280
363
return Ok ( false ) ;
281
364
}
282
- sig . hashing_algorithm ( )
365
+ hash_alg = Some ( pkcs_sig . hashing_algorithm ( ) ) ;
283
366
}
284
367
_ => {
285
368
return Err ( Error :: WrapperError ( WrapperErrorKind :: UnsupportedParam ) ) ;
286
369
}
287
370
} ;
371
+
372
+ let Some ( hash_alg) = hash_alg else {
373
+ return Ok ( false ) ;
374
+ } ;
288
375
if qualifying_data != attest. extra_data ( ) . as_bytes ( ) {
289
376
return Ok ( false ) ;
290
377
}
0 commit comments