• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #[cfg(test)]
18 mod tests {
19     use diced_open_dice::{
20         derive_cdi_certificate_id, derive_cdi_private_key_seed, hash, kdf, keypair_from_seed,
21         retry_sign_cose_sign1, retry_sign_cose_sign1_with_cdi_leaf_priv, sign, verify,
22         DiceArtifacts, PrivateKey, CDI_SIZE, HASH_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
23     };
24     #[cfg(feature = "multialg")]
25     use diced_open_dice::{
26         keypair_from_seed_multialg, retry_sign_cose_sign1_multialg,
27         retry_sign_cose_sign1_with_cdi_leaf_priv_multialg, verify_multialg, KeyAlgorithm,
28     };
29 
30     use coset::{CborSerializable, CoseSign1};
31 
32     // This test initialization is only required for the trusty test harness.
33     #[cfg(feature = "trusty")]
34     test::init!();
35 
36     #[test]
hash_succeeds()37     fn hash_succeeds() {
38         const EXPECTED_HASH: [u8; HASH_SIZE] = [
39             0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02,
40             0xf2, 0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8,
41             0x6d, 0x4c, 0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda,
42             0x34, 0x25, 0x5b, 0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d,
43             0xc5, 0x54, 0x2e, 0x93, 0xae, 0x9c, 0xd7, 0x6f,
44         ];
45         assert_eq!(EXPECTED_HASH, hash(b"hello world").expect("hash failed"));
46     }
47 
48     #[test]
kdf_succeeds()49     fn kdf_succeeds() {
50         let mut derived_key = [0u8; PRIVATE_KEY_SEED_SIZE];
51         kdf(b"myInitialKeyMaterial", b"mySalt", b"myInfo", &mut derived_key).unwrap();
52         const EXPECTED_DERIVED_KEY: [u8; PRIVATE_KEY_SEED_SIZE] = [
53             0x91, 0x9b, 0x8d, 0x29, 0xc4, 0x1b, 0x93, 0xd7, 0xeb, 0x09, 0xfa, 0xd7, 0xc9, 0x87,
54             0xb0, 0xd1, 0xcc, 0x26, 0xef, 0x07, 0x83, 0x42, 0xcf, 0xa3, 0x45, 0x0a, 0x57, 0xe9,
55             0x19, 0x86, 0xef, 0x48,
56         ];
57         assert_eq!(EXPECTED_DERIVED_KEY, derived_key);
58     }
59 
60     #[test]
derive_cdi_certificate_id_succeeds()61     fn derive_cdi_certificate_id_succeeds() {
62         const EXPECTED_ID: [u8; ID_SIZE] = [
63             0x7a, 0x36, 0x45, 0x2c, 0x02, 0xf6, 0x2b, 0xec, 0xf9, 0x80, 0x06, 0x75, 0x87, 0xa5,
64             0xc1, 0x44, 0x0c, 0xd3, 0xc0, 0x6d,
65         ];
66         assert_eq!(EXPECTED_ID, derive_cdi_certificate_id(b"MyPubKey").unwrap());
67     }
68 
69     const EXPECTED_SEED: &[u8] = &[
70         0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
71         0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
72         0x3a, 0x08, 0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28,
73         0xd6, 0x06, 0xa7, 0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41,
74         0x94, 0xd8, 0x8c, 0xa8,
75     ];
76 
77     const EXPECTED_CDI_ATTEST: &[u8; CDI_SIZE] = &[
78         0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
79         0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
80         0x3a, 0x08,
81     ];
82 
83     const EXPECTED_CDI_PRIVATE_KEY_SEED: &[u8] = &[
84         0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
85         0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
86         0x02, 0x6e,
87     ];
88 
89     const EXPECTED_PUB_KEY: &[u8] = &[
90         0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23,
91         0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61,
92         0x06, 0x37,
93     ];
94     const EXPECTED_PRIV_KEY: &[u8] = &[
95         0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
96         0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
97         0x02, 0x6e, 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b,
98         0xfc, 0x23, 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52,
99         0xf1, 0x61, 0x06, 0x37,
100     ];
101     #[cfg(feature = "multialg")]
102     const EXPECTED_EC_P256_PUB_KEY: &[u8] = &[
103         0xa7, 0x93, 0x70, 0x16, 0xff, 0xe8, 0x3c, 0x23, 0x5f, 0x6b, 0xf9, 0x38, 0x7e, 0x9c, 0xe5,
104         0x21, 0xb5, 0x8a, 0x9b, 0x68, 0x5a, 0x2f, 0x62, 0xf4, 0x15, 0x94, 0x1c, 0x61, 0xb3, 0xbb,
105         0xe1, 0x26, 0x61, 0x47, 0x97, 0xbf, 0x3a, 0x1f, 0x6b, 0x87, 0x86, 0x47, 0x5e, 0xc3, 0xa6,
106         0x8b, 0x95, 0x89, 0x9e, 0x29, 0xd5, 0x55, 0x2a, 0xdd, 0x2a, 0x3f, 0xe5, 0xf0, 0x7a, 0xd6,
107         0xc4, 0x7b, 0x64, 0xe0,
108     ];
109     #[cfg(feature = "multialg")]
110     const EXPECTED_EC_P256_PRIV_KEY: &[u8] = &[
111         0x62, 0x32, 0x1b, 0xb, 0x5c, 0xac, 0x8f, 0x20, 0x61, 0xb7, 0xa3, 0xbb, 0x46, 0x2b, 0x4e,
112         0xb3, 0x3f, 0xa7, 0xf6, 0x9b, 0x2f, 0x5b, 0x80, 0xa8, 0x55, 0x5e, 0x80, 0x26, 0xbb, 0x72,
113         0xbe, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
114         0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
115     ];
116     const EXPECTED_SIGNATURE: &[u8] = &[
117         0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2,
118         0x32, 0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29,
119         0x3c, 0x26, 0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd,
120         0x62, 0x8d, 0xf6, 0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc,
121         0xbb, 0xab, 0x4a, 0x0e,
122     ];
123 
124     #[test]
hash_derive_sign_verify()125     fn hash_derive_sign_verify() {
126         let (pub_key, priv_key) = get_test_key_pair();
127 
128         let mut signature = sign(b"MyMessage", priv_key.as_array()).unwrap();
129         assert_eq!(&signature, EXPECTED_SIGNATURE);
130         assert!(verify(b"MyMessage", &signature, &pub_key).is_ok());
131         assert!(verify(b"MyMessage_fail", &signature, &pub_key).is_err());
132         signature[0] += 1;
133         assert!(verify(b"MyMessage", &signature, &pub_key).is_err());
134     }
135 
136     #[test]
sign_cose_sign1_verify()137     fn sign_cose_sign1_verify() {
138         let (pub_key, priv_key) = get_test_key_pair();
139 
140         let signature_res = retry_sign_cose_sign1(b"MyMessage", b"MyAad", priv_key.as_array());
141         assert!(signature_res.is_ok());
142         let signature = signature_res.unwrap();
143         let cose_sign1_res = CoseSign1::from_slice(&signature);
144         assert!(cose_sign1_res.is_ok());
145         let mut cose_sign1 = cose_sign1_res.unwrap();
146 
147         let mut verify_result =
148             cose_sign1.verify_signature(b"MyAad", |sign, data| verify(data, sign, &pub_key));
149         assert!(verify_result.is_ok());
150 
151         verify_result =
152             cose_sign1.verify_signature(b"BadAad", |sign, data| verify(data, sign, &pub_key));
153         assert!(verify_result.is_err());
154 
155         // if we modify the signature, the payload should no longer verify
156         cose_sign1.signature.push(0xAA);
157         verify_result =
158             cose_sign1.verify_signature(b"MyAad", |sign, data| verify(data, sign, &pub_key));
159         assert!(verify_result.is_err());
160     }
161 
162     #[cfg(feature = "multialg")]
163     #[test]
sign_cose_sign1_verify_multialg()164     fn sign_cose_sign1_verify_multialg() {
165         let (pub_key, priv_key) = get_test_key_pair_ec_p256();
166 
167         let signature_res = retry_sign_cose_sign1_multialg(
168             b"MyMessage",
169             b"MyAad",
170             priv_key.as_array(),
171             KeyAlgorithm::EcdsaP256,
172         );
173         assert!(signature_res.is_ok());
174         let signature = signature_res.unwrap();
175         let cose_sign1_res = CoseSign1::from_slice(&signature);
176         assert!(cose_sign1_res.is_ok());
177         let mut cose_sign1 = cose_sign1_res.unwrap();
178 
179         let mut verify_result = cose_sign1.verify_signature(b"MyAad", |sign, data| {
180             verify_multialg(data, sign, &pub_key, KeyAlgorithm::EcdsaP256)
181         });
182         assert!(verify_result.is_ok());
183 
184         verify_result = cose_sign1.verify_signature(b"BadAad", |sign, data| {
185             verify_multialg(data, sign, &pub_key, KeyAlgorithm::EcdsaP256)
186         });
187         assert!(verify_result.is_err());
188 
189         // if we modify the signature, the payload should no longer verify
190         cose_sign1.signature.push(0xAA);
191         verify_result = cose_sign1.verify_signature(b"MyAad", |sign, data| {
192             verify_multialg(data, sign, &pub_key, KeyAlgorithm::EcdsaP256)
193         });
194         assert!(verify_result.is_err());
195     }
196 
197     struct TestArtifactsForSigning {}
198 
199     impl DiceArtifacts for TestArtifactsForSigning {
cdi_attest(&self) -> &[u8; CDI_SIZE]200         fn cdi_attest(&self) -> &[u8; CDI_SIZE] {
201             EXPECTED_CDI_ATTEST
202         }
203 
cdi_seal(&self) -> &[u8; CDI_SIZE]204         fn cdi_seal(&self) -> &[u8; CDI_SIZE] {
205             unimplemented!("no test functionality depends on this")
206         }
207 
bcc(&self) -> Option<&[u8]>208         fn bcc(&self) -> Option<&[u8]> {
209             unimplemented!("no test functionality depends on this")
210         }
211     }
212 
213     #[test]
sign_cose_sign1_with_cdi_leaf_priv_verify()214     fn sign_cose_sign1_with_cdi_leaf_priv_verify() {
215         let dice = TestArtifactsForSigning {};
216 
217         let signature_res = retry_sign_cose_sign1_with_cdi_leaf_priv(b"MyMessage", b"MyAad", &dice);
218         assert!(signature_res.is_ok());
219         let signature = signature_res.unwrap();
220         let cose_sign1_res = CoseSign1::from_slice(&signature);
221         assert!(cose_sign1_res.is_ok());
222         let mut cose_sign1 = cose_sign1_res.unwrap();
223 
224         let mut verify_result = cose_sign1
225             .verify_signature(b"MyAad", |sign, data| verify(data, sign, EXPECTED_PUB_KEY));
226         assert!(verify_result.is_ok());
227 
228         verify_result = cose_sign1
229             .verify_signature(b"BadAad", |sign, data| verify(data, sign, EXPECTED_PUB_KEY));
230         assert!(verify_result.is_err());
231 
232         // if we modify the signature, the payload should no longer verify
233         cose_sign1.signature.push(0xAA);
234         verify_result = cose_sign1
235             .verify_signature(b"MyAad", |sign, data| verify(data, sign, EXPECTED_PUB_KEY));
236         assert!(verify_result.is_err());
237     }
238 
239     #[cfg(feature = "multialg")]
240     #[test]
sign_cose_sign1_with_cdi_leaf_priv_verify_multialg()241     fn sign_cose_sign1_with_cdi_leaf_priv_verify_multialg() {
242         let dice = TestArtifactsForSigning {};
243 
244         let signature_res = retry_sign_cose_sign1_with_cdi_leaf_priv_multialg(
245             b"MyMessage",
246             b"MyAad",
247             &dice,
248             KeyAlgorithm::EcdsaP256,
249         );
250         assert!(signature_res.is_ok());
251         let signature = signature_res.unwrap();
252         let cose_sign1_res = CoseSign1::from_slice(&signature);
253         assert!(cose_sign1_res.is_ok());
254         let mut cose_sign1 = cose_sign1_res.unwrap();
255 
256         let mut verify_result = cose_sign1.verify_signature(b"MyAad", |sign, data| {
257             verify_multialg(data, sign, EXPECTED_EC_P256_PUB_KEY, KeyAlgorithm::EcdsaP256)
258         });
259         assert!(verify_result.is_ok());
260 
261         verify_result = cose_sign1.verify_signature(b"BadAad", |sign, data| {
262             verify_multialg(data, sign, EXPECTED_EC_P256_PUB_KEY, KeyAlgorithm::EcdsaP256)
263         });
264         assert!(verify_result.is_err());
265 
266         // if we modify the signature, the payload should no longer verify
267         cose_sign1.signature.push(0xAA);
268         verify_result = cose_sign1.verify_signature(b"MyAad", |sign, data| {
269             verify_multialg(data, sign, EXPECTED_EC_P256_PUB_KEY, KeyAlgorithm::EcdsaP256)
270         });
271         assert!(verify_result.is_err());
272     }
273 
get_test_key_pair() -> (Vec<u8>, PrivateKey)274     fn get_test_key_pair() -> (Vec<u8>, PrivateKey) {
275         let seed = hash(b"MySeedString").unwrap();
276         assert_eq!(seed, EXPECTED_SEED);
277         let cdi_attest = &seed[..CDI_SIZE];
278         assert_eq!(cdi_attest, EXPECTED_CDI_ATTEST);
279         let cdi_private_key_seed =
280             derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
281         assert_eq!(cdi_private_key_seed.as_array(), EXPECTED_CDI_PRIVATE_KEY_SEED);
282         let (pub_key, priv_key) = keypair_from_seed(cdi_private_key_seed.as_array()).unwrap();
283         assert_eq!(&pub_key, EXPECTED_PUB_KEY);
284         assert_eq!(priv_key.as_array(), EXPECTED_PRIV_KEY);
285 
286         (pub_key, priv_key)
287     }
288 
289     #[cfg(feature = "multialg")]
get_test_key_pair_ec_p256() -> (Vec<u8>, PrivateKey)290     fn get_test_key_pair_ec_p256() -> (Vec<u8>, PrivateKey) {
291         let seed = hash(b"MySeedString").unwrap();
292         assert_eq!(seed, EXPECTED_SEED);
293         let cdi_attest = &seed[..CDI_SIZE];
294         assert_eq!(cdi_attest, EXPECTED_CDI_ATTEST);
295         let cdi_private_key_seed =
296             derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
297         assert_eq!(cdi_private_key_seed.as_array(), EXPECTED_CDI_PRIVATE_KEY_SEED);
298         let (pub_key, priv_key) =
299             keypair_from_seed_multialg(cdi_private_key_seed.as_array(), KeyAlgorithm::EcdsaP256)
300                 .unwrap();
301 
302         assert_eq!(&pub_key, EXPECTED_EC_P256_PUB_KEY);
303         assert_eq!(priv_key.as_array(), EXPECTED_EC_P256_PRIV_KEY);
304 
305         (pub_key, priv_key)
306     }
307 }
308