• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 //! Unit tests for AuthMgr BE
18 use crate::server::{AuthMgrMessage, AUTHMGR_SERVICE_PORT};
19 use alloc::vec::Vec;
20 use android_hardware_security_see_authmgr::aidl::android::hardware::security::see::authmgr::{
21     DiceChainEntry::DiceChainEntry as AidlDiceChainEntry, DiceLeafArtifacts::DiceLeafArtifacts,
22     DicePolicy::DicePolicy, Error::Error, ExplicitKeyDiceCertChain::ExplicitKeyDiceCertChain,
23     IAuthMgrAuthorization::IAuthMgrAuthorization, SignedConnectionRequest::SignedConnectionRequest,
24 };
25 use authgraph_boringssl::{BoringEcDsa, BoringRng};
26 use authgraph_core::key::{CertChain, DiceChainEntry};
27 use authgraph_core::traits::Rng;
28 use authgraph_core_test::{
29     create_dice_cert_chain_for_guest_os, create_dice_leaf_cert, SAMPLE_INSTANCE_HASH,
30 };
31 use authmgr_common::{
32     signed_connection_request::{
33         ConnectionRequest, TEMP_AUTHMGR_BE_TRANSPORT_ID, TEMP_AUTHMGR_FE_TRANSPORT_ID,
34     },
35     CMD_RAW, CMD_RPC, TOKEN_LENGTH,
36 };
37 use authmgr_common_util::{
38     get_constraint_spec_for_static_trusty_ta, get_constraints_spec_for_trusty_vm,
39     policy_for_dice_node,
40 };
41 use binder::Strong;
42 use coset::CborSerializable;
43 use hello_world_trusted_aidl::aidl::android::trusty::trustedhal::IHelloWorld::IHelloWorld;
44 use rpcbinder::RpcSession;
45 use test::assert_ok;
46 use tipc::{Deserialize, Handle, Serialize, Serializer, TipcError};
47 use trusty_std::alloc::TryAllocFrom;
48 
49 test::init!();
50 
51 #[test]
test_authmgr_connection()52 fn test_authmgr_connection() {
53     assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
54 }
55 
56 #[test]
test_authmgr_rpc_command()57 fn test_authmgr_rpc_command() {
58     // Test the AuthMgr Init Service by sending just CMD_RPC over the connection, expect success.
59 
60     let conn_rpc =
61         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
62     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
63     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
64 }
65 
66 #[test]
test_authmgr_rpc_command_with_session_setup()67 fn test_authmgr_rpc_command_with_session_setup() {
68     // Test the AuthMgr Init Service by sending CMD_RPC over the connection and then setting
69     // up session, expect success.
70 
71     let conn_rpc =
72         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
73     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
74     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
75     let cb = || {
76         let fd = conn_rpc.as_raw_fd();
77         Some(fd)
78     };
79     let rpc_session = RpcSession::new();
80     let _rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
81         rpc_session.setup_preconnected_client(cb),
82         "Failed to setup pre-connected client for the authmgr rpc service."
83     );
84 }
85 
86 #[test]
test_authmgr_init_auth_ok()87 fn test_authmgr_init_auth_ok() {
88     // Test the IAuthMgrAuthorization AIDL interface - initAuthentication, expect success.
89     // Connect and send message indicating the intent to connect to the RPC service
90 
91     let conn_rpc =
92         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
93     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
94     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
95     let cb = || {
96         let fd = conn_rpc.as_raw_fd();
97         Some(fd)
98     };
99     let rpc_session = RpcSession::new();
100     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
101         rpc_session.setup_preconnected_client(cb),
102         "Failed to setup pre-connected client for the authmgr rpc service."
103     );
104     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
105     let (_signing_key, _cdi_values, cert_chain) =
106         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
107     let result_init_auth = rpc_session
108         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
109     let _challenge: [u8; TOKEN_LENGTH] =
110         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
111 }
112 
113 #[test]
test_authmgr_init_auth_with_invalid_dice_chain()114 fn test_authmgr_init_auth_with_invalid_dice_chain() {
115     // Test the IAuthMgrAuthorization AIDL interface - initAuthentication with an invalid
116     // DICE chain, expect error.
117     // Connect and send message indicating the intent to connect to the RPC service
118     let conn_rpc =
119         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
120     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
121     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
122     let cb = || {
123         let fd = conn_rpc.as_raw_fd();
124         Some(fd)
125     };
126     let rpc_session = RpcSession::new();
127     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
128         rpc_session.setup_preconnected_client(cb),
129         "Failed to setup pre-connected client for the authmgr rpc service."
130     );
131 
132     let result_init_auth = rpc_session
133         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: Vec::<u8>::new() }, None);
134     assert!(result_init_auth.is_err());
135     assert_eq!(
136         result_init_auth.err().unwrap().service_specific_error(),
137         Error::INVALID_DICE_CERT_CHAIN.0
138     );
139 }
140 
141 #[test]
test_authmgr_init_auth_no_instance_id()142 fn test_authmgr_init_auth_no_instance_id() {
143     // Test the IAuthMgrAuthorization AIDL interface - initAuthentication with no instance id,
144     // expect error.
145     // Connect and send message indicating the intent to connect to the RPC service
146     let conn_rpc =
147         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
148     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
149     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
150     let cb = || {
151         let fd = conn_rpc.as_raw_fd();
152         Some(fd)
153     };
154     let rpc_session = RpcSession::new();
155     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
156         rpc_session.setup_preconnected_client(cb),
157         "Failed to setup pre-connected client for the authmgr rpc service."
158     );
159     // Create a test DICE chain (with CDI secrets for signing) without instance hash
160     let (_signing_key, _cdi_values, cert_chain) = create_dice_cert_chain_for_guest_os(None, 1);
161     let result_init_auth = rpc_session
162         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
163     // Expect error because the instance hash is neither in the DICE chain nor provided externally
164     assert!(result_init_auth.is_err());
165     assert_eq!(
166         result_init_auth.err().unwrap().service_specific_error(),
167         Error::INVALID_INSTANCE_IDENTIFIER.0
168     );
169 }
170 
171 #[test]
test_authmgr_duplicate_init_auth_with_same_vm_id()172 fn test_authmgr_duplicate_init_auth_with_same_vm_id() {
173     // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, from
174     // the same transport id (i.e. VM-ID), expect error.
175     // Connect and send message indicating the intent to connect to the RPC service
176     let conn_rpc =
177         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
178     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
179     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
180     let cb = || {
181         let fd = conn_rpc.as_raw_fd();
182         Some(fd)
183     };
184     let rpc_session = RpcSession::new();
185     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
186         rpc_session.setup_preconnected_client(cb),
187         "Failed to setup pre-connected client for the authmgr rpc service."
188     );
189     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
190     let (_signing_key, _cdi_values, cert_chain) =
191         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
192     let result_init_auth = rpc_session
193         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain.clone() }, None);
194     let _challenge: [u8; TOKEN_LENGTH] =
195         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
196 
197     let result_init_auth2 = rpc_session
198         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
199     assert!(result_init_auth2.is_err());
200     assert_eq!(
201         result_init_auth2.err().unwrap().service_specific_error(),
202         Error::AUTHENTICATION_ALREADY_STARTED.0
203     );
204 }
205 
206 #[test]
test_authmgr_duplicate_init_auth_with_same_vm_id_after_cache_cleanup()207 fn test_authmgr_duplicate_init_auth_with_same_vm_id_after_cache_cleanup() {
208     // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, from
209     // the same transport id (i.e. VM-ID), but after cache cleanup triggered by closing the initial
210     // connection, expect success.
211     // Connect and send message indicating the intent to connect to the RPC service
212     let conn_rpc =
213         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
214     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
215     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
216     let cb = || {
217         let fd = conn_rpc.as_raw_fd();
218         Some(fd)
219     };
220     let rpc_session = RpcSession::new();
221     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
222         rpc_session.setup_preconnected_client(cb),
223         "Failed to setup pre-connected client for the authmgr rpc service."
224     );
225     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
226     let (_signing_key, _cdi_values, cert_chain) =
227         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
228     let result_init_auth = rpc_session
229         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain.clone() }, None);
230     let _challenge: [u8; TOKEN_LENGTH] =
231         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
232     // Drop the first connection to trigger cache cleanup
233     core::mem::drop(conn_rpc);
234 
235     // Setup a new connection
236     let conn_rpc_2 =
237         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
238     assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
239     let cb_authmgr_2 = || {
240         let fd = conn_rpc_2.as_raw_fd();
241         Some(fd)
242     };
243 
244     // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
245     let rpc_session_2 = RpcSession::new();
246     let rpc_session_2: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
247         rpc_session_2.setup_preconnected_client(cb_authmgr_2),
248         "Failed to setup pre-connected client for the authmgr rpc service."
249     );
250 
251     let result_init_auth2 = rpc_session_2
252         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain }, None);
253     let _challenge: [u8; TOKEN_LENGTH] = assert_ok!(result_init_auth2);
254 }
255 
256 #[test]
test_authmgr_complete_auth_ok()257 fn test_authmgr_complete_auth_ok() {
258     // Test the IAuthMgrAuthorization AIDL interface - completeAuthentication, expect success.
259     let conn_rpc =
260         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
261     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
262     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
263     let cb = || {
264         let fd = conn_rpc.as_raw_fd();
265         Some(fd)
266     };
267     let rpc_session = RpcSession::new();
268     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
269         rpc_session.setup_preconnected_client(cb),
270         "Failed to setup pre-connected client for the authmgr rpc service."
271     );
272     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
273     let (signing_key, _cdi_values, cert_chain_bytes) =
274         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
275     let result_init_auth = rpc_session.initAuthentication(
276         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
277         None,
278     );
279     let challenge: [u8; TOKEN_LENGTH] =
280         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
281 
282     let cert_chain =
283         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
284     // Build the connection request to be signed
285     let conn_req = ConnectionRequest::new_for_ffa_transport(
286         challenge,
287         TEMP_AUTHMGR_FE_TRANSPORT_ID,
288         TEMP_AUTHMGR_BE_TRANSPORT_ID,
289     );
290     // Sign the connection request with the DICE CDI secrets
291     let ecdsa = BoringEcDsa;
292     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
293     let signing_algorithm = verify_key.get_cose_sign_algorithm();
294     let signature = assert_ok!(
295         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
296         "Failed to sign connection request"
297     );
298     // Create a DICE policy
299     let constraint_spec = get_constraints_spec_for_trusty_vm();
300     let policy = assert_ok!(
301         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
302         "Failed to building policy for pvm"
303     );
304 
305     // ****** Invoke step 2 of phase 1 of the protocol ******
306     let result_complete_auth = rpc_session.completeAuthentication(
307         &SignedConnectionRequest { signedConnectionRequest: signature },
308         &DicePolicy {
309             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
310         },
311     );
312     assert_ok!(result_complete_auth);
313 }
314 
315 #[test]
test_authmgr_duplicate_init_auth_on_authenticated_connection()316 fn test_authmgr_duplicate_init_auth_on_authenticated_connection() {
317     // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, over
318     // an already authenticated connection, expect error.
319     // Connect and send message indicating the intent to connect to the RPC service
320     let conn_rpc =
321         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
322     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
323     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
324     let cb = || {
325         let fd = conn_rpc.as_raw_fd();
326         Some(fd)
327     };
328     let rpc_session = RpcSession::new();
329     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
330         rpc_session.setup_preconnected_client(cb),
331         "Failed to setup pre-connected client for the authmgr rpc service."
332     );
333     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
334     let (signing_key, _cdi_values, cert_chain_bytes) =
335         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
336     let result_init_auth = rpc_session.initAuthentication(
337         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
338         None,
339     );
340     let challenge: [u8; TOKEN_LENGTH] =
341         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
342 
343     let cert_chain =
344         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
345     // Build the connection request to be signed
346     let conn_req = ConnectionRequest::new_for_ffa_transport(
347         challenge,
348         TEMP_AUTHMGR_FE_TRANSPORT_ID,
349         TEMP_AUTHMGR_BE_TRANSPORT_ID,
350     );
351     // Sign the connection request with the DICE CDI secrets
352     let ecdsa = BoringEcDsa;
353     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
354     let signing_algorithm = verify_key.get_cose_sign_algorithm();
355     let signature = assert_ok!(
356         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
357         "Failed to sign connection request"
358     );
359     // Create a DICE policy
360     let constraint_spec = get_constraints_spec_for_trusty_vm();
361     let policy = assert_ok!(
362         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
363         "Failed to building policy for pvm"
364     );
365 
366     // ****** Invoke step 2 of phase 1 of the protocol ******
367     let result_complete_auth = rpc_session.completeAuthentication(
368         &SignedConnectionRequest { signedConnectionRequest: signature },
369         &DicePolicy {
370             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
371         },
372     );
373     assert_ok!(result_complete_auth);
374 
375     // ******* Invoke step 1 of phase 1 of the protocol over the same connection ********
376     let result_init_auth2 = rpc_session
377         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes }, None);
378     assert!(result_init_auth2.is_err());
379     assert_eq!(
380         result_init_auth2.err().unwrap().service_specific_error(),
381         Error::INSTANCE_ALREADY_AUTHENTICATED.0
382     );
383 }
384 
385 #[test]
test_authmgr_duplicate_init_auth_with_same_instance_id_of_authenticatd_vm_on_new_connection()386 fn test_authmgr_duplicate_init_auth_with_same_instance_id_of_authenticatd_vm_on_new_connection() {
387     // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, using
388     // the same instance id of an authenticated pvm, over a new connection, expect error.
389     // Connect and send message indicating the intent to connect to the RPC service
390     let conn_rpc =
391         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
392     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
393     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
394     let cb = || {
395         let fd = conn_rpc.as_raw_fd();
396         Some(fd)
397     };
398     let rpc_session = RpcSession::new();
399     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
400         rpc_session.setup_preconnected_client(cb),
401         "Failed to setup pre-connected client for the authmgr rpc service."
402     );
403     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
404     let (signing_key, _cdi_values, cert_chain_bytes) =
405         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
406     let result_init_auth = rpc_session.initAuthentication(
407         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
408         None,
409     );
410     let challenge: [u8; TOKEN_LENGTH] =
411         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
412 
413     let cert_chain =
414         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
415     // Build the connection request to be signed
416     let conn_req = ConnectionRequest::new_for_ffa_transport(
417         challenge,
418         TEMP_AUTHMGR_FE_TRANSPORT_ID,
419         TEMP_AUTHMGR_BE_TRANSPORT_ID,
420     );
421     // Sign the connection request with the DICE CDI secrets
422     let ecdsa = BoringEcDsa;
423     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
424     let signing_algorithm = verify_key.get_cose_sign_algorithm();
425     let signature = assert_ok!(
426         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
427         "Failed to sign connection request"
428     );
429     // Create a DICE policy
430     let constraint_spec = get_constraints_spec_for_trusty_vm();
431     let policy = assert_ok!(
432         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
433         "Failed to building policy for pvm"
434     );
435 
436     // ****** Invoke step 2 of phase 1 of the protocol ******
437     let result_complete_auth = rpc_session.completeAuthentication(
438         &SignedConnectionRequest { signedConnectionRequest: signature },
439         &DicePolicy {
440             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
441         },
442     );
443     assert_ok!(result_complete_auth);
444 
445     // ******* Invoke step 1 of phase 1 of the protocol over a different connection ********
446     let conn_rpc_2 = assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT));
447     assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
448     let cb_authmgr_2 = || {
449         let fd = conn_rpc_2.as_raw_fd();
450         Some(fd)
451     };
452 
453     // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
454     let rpc_session_2 = RpcSession::new();
455     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
456         rpc_session_2.setup_preconnected_client(cb_authmgr_2),
457         "Failed to setup pre-connected client for the authmgr rpc service."
458     );
459 
460     let result_init_auth2 = rpc_session
461         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes }, None);
462     assert!(result_init_auth2.is_err());
463     assert_eq!(
464         result_init_auth2.err().unwrap().service_specific_error(),
465         Error::INSTANCE_ALREADY_AUTHENTICATED.0
466     );
467 }
468 
469 #[test]
test_authmgr_duplicate_init_auth_with_diff_instance_ids_same_vm_id_of_authenticatd_vm_on_new_connection( )470 fn test_authmgr_duplicate_init_auth_with_diff_instance_ids_same_vm_id_of_authenticatd_vm_on_new_connection(
471 ) {
472     // Test the IAuthMgrAuthorization AIDL interface - with two calls to initAuthentication, using
473     // different instance ids, but the same vm-id of an authenticated pvm, over a new connection,
474     // expect error.
475     // Connect and send message indicating the intent to connect to the RPC service
476     let conn_rpc =
477         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
478     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
479     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
480     let cb = || {
481         let fd = conn_rpc.as_raw_fd();
482         Some(fd)
483     };
484     let rpc_session = RpcSession::new();
485     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
486         rpc_session.setup_preconnected_client(cb),
487         "Failed to setup pre-connected client for the authmgr rpc service."
488     );
489     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
490     let (signing_key, _cdi_values, cert_chain_bytes) =
491         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
492     let result_init_auth = rpc_session.initAuthentication(
493         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
494         None,
495     );
496     let challenge: [u8; TOKEN_LENGTH] =
497         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
498 
499     let cert_chain =
500         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
501     // Build the connection request to be signed
502     let conn_req = ConnectionRequest::new_for_ffa_transport(
503         challenge,
504         TEMP_AUTHMGR_FE_TRANSPORT_ID,
505         TEMP_AUTHMGR_BE_TRANSPORT_ID,
506     );
507     // Sign the connection request with the DICE CDI secrets
508     let ecdsa = BoringEcDsa;
509     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
510     let signing_algorithm = verify_key.get_cose_sign_algorithm();
511     let signature = assert_ok!(
512         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
513         "Failed to sign connection request"
514     );
515     // Create a DICE policy
516     let constraint_spec = get_constraints_spec_for_trusty_vm();
517     let policy = assert_ok!(
518         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
519         "Failed to building policy for pvm"
520     );
521 
522     // ****** Invoke step 2 of phase 1 of the protocol ******
523     let result_complete_auth = rpc_session.completeAuthentication(
524         &SignedConnectionRequest { signedConnectionRequest: signature },
525         &DicePolicy {
526             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
527         },
528     );
529     assert_ok!(result_complete_auth);
530 
531     // Create a DICE chain with a different instance hash
532     pub const DIFF_INSTANCE_HASH: [u8; 64] = [
533         0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x21, 0x09, 0x9c, 0xf3, 0xcd, 0xc7, 0xa4,
534         0x2a, 0x7d, 0x7e, 0xf5, 0x8e, 0xd6, 0x4d, 0x82, 0x25, 0x1a, 0x51, 0x27, 0x9d, 0x55, 0x8a,
535         0xe9, 0x90, 0xf5, 0x8e, 0xd6, 0x4d, 0x84, 0x25, 0x1a, 0x51, 0x27, 0x9d, 0x5b, 0x3f, 0xc9,
536         0x6a, 0xe3, 0x95, 0x59, 0x40, 0x21, 0x09, 0x3d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0x7d, 0x7e,
537         0xf5, 0x8e, 0xf5, 0x8e,
538     ];
539     let (_signing_key_2, _cdi_values_2, cert_chain_bytes_2) =
540         create_dice_cert_chain_for_guest_os(Some(DIFF_INSTANCE_HASH), 1);
541 
542     // ******* Invoke step 1 of phase 1 of the protocol over a different connection ********
543     let conn_rpc_2 = assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT));
544     assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
545     let cb_authmgr_2 = || {
546         let fd = conn_rpc_2.as_raw_fd();
547         Some(fd)
548     };
549 
550     // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
551     let rpc_session_2 = RpcSession::new();
552     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
553         rpc_session_2.setup_preconnected_client(cb_authmgr_2),
554         "Failed to setup pre-connected client for the authmgr rpc service."
555     );
556 
557     let result_init_auth2 = rpc_session
558         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes_2 }, None);
559     assert!(result_init_auth2.is_err());
560     assert_eq!(
561         result_init_auth2.err().unwrap().service_specific_error(),
562         Error::INSTANCE_ALREADY_AUTHENTICATED.0
563     );
564 }
565 
566 #[test]
test_authmgr_raw_command_without_authentication()567 fn test_authmgr_raw_command_without_authentication() {
568     // Test the AuthMgr Init Service by sending CMD_RAW over the connection, which should result in
569     // an error and connection close at the service side because the previous steps of the protocol
570     // have not been performed yet. The only way we can assert that this results in an error in the
571     // service is by waiting for `recv` on the connection and trying to send another command and
572     // asserting that it fails.
573     let conn_raw =
574         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
575 
576     let mut token = [0u8; TOKEN_LENGTH];
577     let boring_rng = BoringRng;
578     boring_rng.fill_bytes(&mut token);
579     let mut msg = Vec::<u8>::new();
580     msg.push(CMD_RAW);
581     msg.extend_from_slice(&token);
582     let cmd_raw = AuthMgrMessage(msg);
583     assert_ok!(conn_raw.send(&cmd_raw));
584 
585     pub struct AuthMgrMessage(pub Vec<u8>);
586 
587     impl Deserialize for AuthMgrMessage {
588         type Error = TipcError;
589         const MAX_SERIALIZED_SIZE: usize = 4000;
590 
591         fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, TipcError> {
592             Ok(AuthMgrMessage(Vec::try_alloc_from(bytes)?))
593         }
594     }
595 
596     impl<'s> Serialize<'s> for AuthMgrMessage {
597         fn serialize<'a: 's, S: Serializer<'s>>(
598             &'a self,
599             serializer: &mut S,
600         ) -> Result<S::Ok, S::Error> {
601             serializer.serialize_bytes(self.0.as_slice())
602         }
603     }
604 
605     let mut buf = [0u8; 1];
606     let _resul: Result<AuthMgrMessage, TipcError> = conn_raw.recv(&mut buf);
607 
608     let result2 = conn_raw.send(&cmd_raw);
609     assert!(result2.is_err());
610 }
611 
612 #[test]
test_authmgr_complete_auth_without_init_auth()613 fn test_authmgr_complete_auth_without_init_auth() {
614     // Test IAuthMgrAuthorization AIDL interface - by invoking completeAuthentication without
615     // invoking initAuthentication before - expect error
616     let conn_rpc =
617         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
618     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
619     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
620     let cb = || {
621         let fd = conn_rpc.as_raw_fd();
622         Some(fd)
623     };
624     let rpc_session = RpcSession::new();
625     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
626         rpc_session.setup_preconnected_client(cb),
627         "Failed to setup pre-connected client for the authmgr rpc service."
628     );
629     let result_complete_auth = rpc_session.completeAuthentication(
630         &SignedConnectionRequest { signedConnectionRequest: Vec::new() },
631         &DicePolicy { dicePolicy: Vec::new() },
632     );
633     assert!(result_complete_auth.is_err());
634     assert_eq!(
635         result_complete_auth.err().unwrap().service_specific_error(),
636         Error::AUTHENTICATION_NOT_STARTED.0
637     );
638 }
639 
640 #[test]
test_authmgr_duplicate_complete_auth_on_the_same_connection()641 fn test_authmgr_duplicate_complete_auth_on_the_same_connection() {
642     // Test IAuthMgrAuthorization AIDL interface - by invoking completeAuthentication on an alerady
643     // authenticated connection.
644     let conn_rpc =
645         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
646     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
647     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
648     let cb = || {
649         let fd = conn_rpc.as_raw_fd();
650         Some(fd)
651     };
652     let rpc_session = RpcSession::new();
653     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
654         rpc_session.setup_preconnected_client(cb),
655         "Failed to setup pre-connected client for the authmgr rpc service."
656     );
657     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
658     let (signing_key, _cdi_values, cert_chain_bytes) =
659         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
660     let result_init_auth = rpc_session.initAuthentication(
661         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
662         None,
663     );
664     let challenge: [u8; TOKEN_LENGTH] =
665         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
666 
667     let cert_chain =
668         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
669     // Build the connection request to be signed
670     let conn_req = ConnectionRequest::new_for_ffa_transport(
671         challenge,
672         TEMP_AUTHMGR_FE_TRANSPORT_ID,
673         TEMP_AUTHMGR_BE_TRANSPORT_ID,
674     );
675     // Sign the connection request with the DICE CDI secrets
676     let ecdsa = BoringEcDsa;
677     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
678     let signing_algorithm = verify_key.get_cose_sign_algorithm();
679     let signature = assert_ok!(
680         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
681         "Failed to sign connection request"
682     );
683     // Create a DICE policy
684     let constraint_spec = get_constraints_spec_for_trusty_vm();
685     let policy = assert_ok!(
686         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
687         "Failed to building policy for pvm"
688     );
689 
690     // ****** Invoke step 2 of phase 1 of the protocol ******
691     let result_complete_auth = rpc_session.completeAuthentication(
692         &SignedConnectionRequest { signedConnectionRequest: signature.clone() },
693         &DicePolicy {
694             dicePolicy: assert_ok!(policy.clone().to_vec(), "Failed to encode DICE policy for pvm"),
695         },
696     );
697     assert_ok!(result_complete_auth);
698 
699     let result_complete_auth2 = rpc_session.completeAuthentication(
700         &SignedConnectionRequest { signedConnectionRequest: signature },
701         &DicePolicy {
702             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
703         },
704     );
705     assert!(result_complete_auth2.is_err());
706     assert_eq!(
707         result_complete_auth2.err().unwrap().service_specific_error(),
708         Error::INSTANCE_ALREADY_AUTHENTICATED.0
709     );
710 }
711 
712 #[test]
test_authmgr_duplicate_complete_auth_on_new_connection()713 fn test_authmgr_duplicate_complete_auth_on_new_connection() {
714     // Test the IAuthMgrAuthorization AIDL interface - by invoking completeAuthentication from
715     // an authenticated pvm, over a new connection, expect error.
716     // Connect and send message indicating the intent to connect to the RPC service
717     let conn_rpc =
718         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
719     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
720     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
721     let cb = || {
722         let fd = conn_rpc.as_raw_fd();
723         Some(fd)
724     };
725     let rpc_session = RpcSession::new();
726     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
727         rpc_session.setup_preconnected_client(cb),
728         "Failed to setup pre-connected client for the authmgr rpc service."
729     );
730     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
731     let (signing_key, _cdi_values, cert_chain_bytes) =
732         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
733     let result_init_auth = rpc_session.initAuthentication(
734         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
735         None,
736     );
737     let challenge: [u8; TOKEN_LENGTH] =
738         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
739 
740     let cert_chain =
741         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
742     // Build the connection request to be signed
743     let conn_req = ConnectionRequest::new_for_ffa_transport(
744         challenge,
745         TEMP_AUTHMGR_FE_TRANSPORT_ID,
746         TEMP_AUTHMGR_BE_TRANSPORT_ID,
747     );
748     // Sign the connection request with the DICE CDI secrets
749     let ecdsa = BoringEcDsa;
750     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
751     let signing_algorithm = verify_key.get_cose_sign_algorithm();
752     let signature = assert_ok!(
753         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
754         "Failed to sign connection request"
755     );
756     // Create a DICE policy
757     let constraint_spec = get_constraints_spec_for_trusty_vm();
758     let policy = assert_ok!(
759         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
760         "Failed to building policy for pvm"
761     );
762 
763     // ****** Invoke step 2 of phase 1 of the protocol ******
764     let result_complete_auth = rpc_session.completeAuthentication(
765         &SignedConnectionRequest { signedConnectionRequest: signature.clone() },
766         &DicePolicy {
767             dicePolicy: assert_ok!(policy.clone().to_vec(), "Failed to encode DICE policy for pvm"),
768         },
769     );
770     assert_ok!(result_complete_auth);
771 
772     // ******* Invoke step 2 of phase 1 of the protocol over a different connection ********
773     let conn_rpc_2 = assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT));
774     assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
775     let cb_authmgr_2 = || {
776         let fd = conn_rpc_2.as_raw_fd();
777         Some(fd)
778     };
779 
780     // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
781     let rpc_session_2 = RpcSession::new();
782     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
783         rpc_session_2.setup_preconnected_client(cb_authmgr_2),
784         "Failed to setup pre-connected client for the authmgr rpc service."
785     );
786 
787     let result_complete_auth_2 = rpc_session.completeAuthentication(
788         &SignedConnectionRequest { signedConnectionRequest: signature },
789         &DicePolicy {
790             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
791         },
792     );
793     assert!(result_complete_auth_2.is_err());
794     assert_eq!(
795         result_complete_auth_2.err().unwrap().service_specific_error(),
796         Error::INSTANCE_ALREADY_AUTHENTICATED.0
797     );
798 }
799 
800 #[test]
test_authmgr_duplicate_complete_auth_after_cache_cleanup()801 fn test_authmgr_duplicate_complete_auth_after_cache_cleanup() {
802     // Test the IAuthMgrAuthorization AIDL interface - with two attempts for phase 1, from
803     // the same transport id (i.e. VM-ID), but after cache cleanup triggered by closing the initial
804     // connection, expect success.
805     // Connect and send message indicating the intent to connect to the RPC service
806     let conn_rpc =
807         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
808     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
809     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
810     let cb = || {
811         let fd = conn_rpc.as_raw_fd();
812         Some(fd)
813     };
814     let rpc_session = RpcSession::new();
815     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
816         rpc_session.setup_preconnected_client(cb),
817         "Failed to setup pre-connected client for the authmgr rpc service."
818     );
819     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
820     let (signing_key, _cdi_values, cert_chain_bytes) =
821         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
822     let result_init_auth = rpc_session.initAuthentication(
823         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
824         None,
825     );
826     let challenge: [u8; TOKEN_LENGTH] =
827         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
828 
829     let cert_chain =
830         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
831     // Build the connection request to be signed
832     let conn_req = ConnectionRequest::new_for_ffa_transport(
833         challenge,
834         TEMP_AUTHMGR_FE_TRANSPORT_ID,
835         TEMP_AUTHMGR_BE_TRANSPORT_ID,
836     );
837     // Sign the connection request with the DICE CDI secrets
838     let ecdsa = BoringEcDsa;
839     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
840     let signing_algorithm = verify_key.get_cose_sign_algorithm();
841     let signature = assert_ok!(
842         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
843         "Failed to sign connection request"
844     );
845     // Create a DICE policy
846     let constraint_spec = get_constraints_spec_for_trusty_vm();
847     let policy = assert_ok!(
848         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
849         "Failed to building policy for pvm"
850     );
851 
852     // ****** Invoke step 2 of phase 1 of the protocol ******
853     let result_complete_auth = rpc_session.completeAuthentication(
854         &SignedConnectionRequest { signedConnectionRequest: signature },
855         &DicePolicy {
856             dicePolicy: assert_ok!(policy.clone().to_vec(), "Failed to encode DICE policy for pvm"),
857         },
858     );
859     assert_ok!(result_complete_auth);
860 
861     // Drop the first connection to trigger cache cleanup
862     core::mem::drop(conn_rpc);
863 
864     // Setup a new connection
865     let conn_rpc_2 =
866         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
867     assert_ok!(conn_rpc_2.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
868     let cb_authmgr_2 = || {
869         let fd = conn_rpc_2.as_raw_fd();
870         Some(fd)
871     };
872 
873     // Setup RPC connection to the AuthMgr service and execute step 1 of phase 1
874     let rpc_session_2 = RpcSession::new();
875     let rpc_session_2: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
876         rpc_session_2.setup_preconnected_client(cb_authmgr_2),
877         "Failed to setup pre-connected client for the authmgr rpc service."
878     );
879 
880     let result_init_auth_2 = rpc_session_2
881         .initAuthentication(&ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes }, None);
882     let challenge_2: [u8; TOKEN_LENGTH] = assert_ok!(result_init_auth_2);
883 
884     // Build the connection request to be signed
885     let conn_req_2 = ConnectionRequest::new_for_ffa_transport(
886         challenge_2,
887         TEMP_AUTHMGR_FE_TRANSPORT_ID,
888         TEMP_AUTHMGR_BE_TRANSPORT_ID,
889     );
890     let signature_2 = assert_ok!(
891         conn_req_2.sign(&signing_key, &ecdsa, signing_algorithm),
892         "Failed to sign connection request"
893     );
894 
895     let result_complete_auth_2 = rpc_session_2.completeAuthentication(
896         &SignedConnectionRequest { signedConnectionRequest: signature_2 },
897         &DicePolicy {
898             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
899         },
900     );
901     assert_ok!(result_complete_auth_2);
902 }
903 
904 #[test]
authmgr_full_protocol_happy_path()905 fn authmgr_full_protocol_happy_path() {
906     // Connect to the TA and send message indicating the intent to connect to the binder RPC service
907     let conn_rpc =
908         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to connect to AuthMgr BE.");
909     let cmd_rpc = AuthMgrMessage(vec![CMD_RPC]);
910     assert_ok!(conn_rpc.send(&cmd_rpc), "Failed to send the command requesting RPC service.");
911     let cb = || {
912         let fd = conn_rpc.as_raw_fd();
913         Some(fd)
914     };
915     let rpc_session = RpcSession::new();
916     let rpc_session: Strong<dyn IAuthMgrAuthorization> = assert_ok!(
917         rpc_session.setup_preconnected_client(cb),
918         "Failed to setup pre-connected client for the authmgr rpc service."
919     );
920     // Create a test DICE chain (with CDI secrets for signing) with an instance hash in vm_entry
921     let (signing_key, cdi_values, cert_chain_bytes) =
922         create_dice_cert_chain_for_guest_os(Some(SAMPLE_INSTANCE_HASH), 1);
923     let result_init_auth = rpc_session.initAuthentication(
924         &ExplicitKeyDiceCertChain { diceCertChain: cert_chain_bytes.clone() },
925         None,
926     );
927     let challenge: [u8; TOKEN_LENGTH] =
928         assert_ok!(result_init_auth, "Failed to invoke initAuthentication.");
929 
930     let cert_chain =
931         assert_ok!(CertChain::from_slice(&cert_chain_bytes), "Failed to decode the cert chain");
932     // Build the connection request to be signed
933     let conn_req = ConnectionRequest::new_for_ffa_transport(
934         challenge,
935         TEMP_AUTHMGR_FE_TRANSPORT_ID,
936         TEMP_AUTHMGR_BE_TRANSPORT_ID,
937     );
938     // Sign the connection request with the DICE CDI secrets
939     let ecdsa = BoringEcDsa;
940     let verify_key = assert_ok!(cert_chain.validate(&ecdsa), "Failed to validate the cert chain");
941     let signing_algorithm = verify_key.get_cose_sign_algorithm();
942     let signature = assert_ok!(
943         conn_req.sign(&signing_key, &ecdsa, signing_algorithm),
944         "Failed to sign connection request"
945     );
946     // Create a DICE policy
947     let constraint_spec = get_constraints_spec_for_trusty_vm();
948     let policy = assert_ok!(
949         dice_policy_builder::policy_for_dice_chain(&cert_chain_bytes, constraint_spec),
950         "Failed to building policy for pvm"
951     );
952 
953     // ****** Invoke step 2 of phase 1 of the protocol ******
954     let result_complete_auth = rpc_session.completeAuthentication(
955         &SignedConnectionRequest { signedConnectionRequest: signature },
956         &DicePolicy {
957             dicePolicy: assert_ok!(policy.to_vec(), "Failed to encode DICE policy for pvm"),
958         },
959     );
960     assert_ok!(result_complete_auth);
961 
962     // Connect to the TA and send a message indicating the intent establish a raw connection and
963     // send a token
964     let conn_raw =
965         assert_ok!(Handle::connect(AUTHMGR_SERVICE_PORT), "Failed to setup a raw connection");
966     let mut token = [0u8; TOKEN_LENGTH];
967     let boring_rng = BoringRng;
968     boring_rng.fill_bytes(&mut token);
969     let mut msg = Vec::<u8>::new();
970     msg.push(CMD_RAW);
971     msg.extend_from_slice(&token);
972     let cmd_raw = AuthMgrMessage(msg);
973     assert_ok!(conn_raw.send(&cmd_raw));
974 
975     // ****** Execute phase 2 of the AuthMgr protocol ******
976     // Create DICE certificate and a DICE policy for the client
977     let leaf_cert_bytes = create_dice_leaf_cert(cdi_values, "keymint", 1);
978     let client_constraint_spec_km = get_constraint_spec_for_static_trusty_ta();
979     let leaf_cert =
980         assert_ok!(DiceChainEntry::from_slice(&leaf_cert_bytes), "Failed to decode leaf cert");
981     let client_policy = assert_ok!(
982         policy_for_dice_node(&leaf_cert, client_constraint_spec_km),
983         "Failed to create policy for leaf cert"
984     );
985     let result_client_authz = rpc_session.authorizeAndConnectClientToTrustedService(
986         &[],
987         "HelloService",
988         &token,
989         &DiceLeafArtifacts {
990             diceLeaf: AidlDiceChainEntry { diceChainEntry: leaf_cert_bytes },
991             diceLeafPolicy: DicePolicy {
992                 dicePolicy: assert_ok!(
993                     client_policy.to_vec(),
994                     "Failed to encode client dice policy."
995                 ),
996             },
997         },
998     );
999     assert_ok!(result_client_authz);
1000 
1001     // Simulate the client connecting to the IHelloWorld example trusted service over the raw
1002     // connection authorized via AuthMgr protocol execution above
1003     let cb_trusted_hal = || {
1004         let fd = conn_raw.as_raw_fd();
1005         Some(fd)
1006     };
1007 
1008     let trusted_service_rpc_session = RpcSession::new();
1009     let trusted_service_rpc_session: Strong<dyn IHelloWorld> = assert_ok!(
1010         trusted_service_rpc_session.setup_preconnected_client(cb_trusted_hal),
1011         "Failed to setup pre-connected client for the trusted service."
1012     );
1013     let result = assert_ok!(trusted_service_rpc_session.sayHello("Test."));
1014     assert_eq!("Hello Test.", result);
1015 }
1016