Skip to content

Commit 42ea804

Browse files
committed
ta: qcom_pas: verify image signature and device bindings
Segment-hash verification proves an image matches its own digest table; it cannot prove who signed it or that it is permitted on this device, so establish provenance before the peripheral leaves reset. The fuse read selecting this path fails closed: an error means secure boot enabled, so a transient failure cannot downgrade a fused board to hash-only verification. UIE-encrypted and QTI-countersigned images are refused, as neither is implemented here, and the chain is limited to one ECDSA P-384 root. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
1 parent 3271193 commit 42ea804

11 files changed

Lines changed: 1143 additions & 9 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: BSD-2-Clause */
2+
/*
3+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
*/
5+
6+
#ifndef __PAS_POLICY_H
7+
#define __PAS_POLICY_H
8+
9+
#include <stdint.h>
10+
#include <tee_api_types.h>
11+
12+
TEE_Result pas_policy_expected_swid(uint32_t pas_id, uint32_t *swid);
13+
14+
#endif /* __PAS_POLICY_H */

ta/qcom_pas/include/auth/pas_sig.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* SPDX-License-Identifier: BSD-2-Clause */
2+
/*
3+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
*/
5+
6+
#ifndef __PAS_AUTH_SIG_H
7+
#define __PAS_AUTH_SIG_H
8+
9+
#include <stdbool.h>
10+
#include <stddef.h>
11+
#include <stdint.h>
12+
#include <tee_api_types.h>
13+
14+
#define PAS_AUTH_MAX_HASH_SIZE 48U
15+
#define PAS_AUTH_MAX_SIG_SIZE 512U
16+
17+
TEE_Result pas_sig_verify_cert_chain(const uint8_t *chain_der,
18+
size_t chain_der_len, bool eku_enforced,
19+
uint32_t num_roots,
20+
uint32_t root_cert_sel,
21+
const uint8_t **leaf_der,
22+
size_t *leaf_der_len,
23+
const uint8_t **roots_der,
24+
size_t *roots_der_len);
25+
26+
TEE_Result pas_sig_check_root_of_trust(uint32_t hash_algo, size_t hash_len,
27+
const uint8_t *root_der,
28+
size_t root_der_len,
29+
const uint8_t *expected);
30+
31+
TEE_Result pas_sig_algo_from_leaf(const uint8_t *leaf_der,
32+
size_t leaf_der_len, uint32_t *sig_algo,
33+
uint32_t *hash_algo);
34+
35+
TEE_Result pas_sig_verify_signature(uint32_t sig_algo, uint32_t hash_algo,
36+
const uint8_t *leaf_der,
37+
size_t leaf_der_len,
38+
const uint8_t *msg, size_t msg_len,
39+
const uint8_t *sig, size_t sig_len);
40+
41+
#endif /* __PAS_AUTH_SIG_H */
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* SPDX-License-Identifier: BSD-2-Clause */
2+
/*
3+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
*/
5+
6+
#ifndef __PAS_SIG_AUTH_H
7+
#define __PAS_SIG_AUTH_H
8+
9+
#include <pas_mbn.h>
10+
#include <pas_meta.h>
11+
#include <tee_internal_api.h>
12+
13+
#ifdef CFG_QCOM_PAS_AUTH
14+
TEE_Result pas_sig_auth_hash_len(const struct pas_md_slot *slot,
15+
uint32_t *hash_len);
16+
17+
TEE_Result pas_sig_auth_authenticate(const struct pas_mbn *hs,
18+
const uint8_t *meta_data,
19+
size_t meta_data_size,
20+
uint32_t pas_id, uint32_t hash_len,
21+
const uint8_t *anchor);
22+
#else
23+
static inline TEE_Result
24+
pas_sig_auth_hash_len(const struct pas_md_slot *slot __unused,
25+
uint32_t *hash_len)
26+
{
27+
*hash_len = TEE_SHA384_HASH_SIZE;
28+
return TEE_SUCCESS;
29+
}
30+
31+
static inline TEE_Result
32+
pas_sig_auth_authenticate(const struct pas_mbn *hs __unused,
33+
const uint8_t *meta_data __unused,
34+
size_t meta_data_size __unused,
35+
uint32_t pas_id __unused,
36+
uint32_t hash_len __unused,
37+
const uint8_t *anchor __unused)
38+
{
39+
return TEE_SUCCESS;
40+
}
41+
#endif /* CFG_QCOM_PAS_AUTH */
42+
43+
#endif /* __PAS_SIG_AUTH_H */

ta/qcom_pas/src/auth/pas_auth.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
*/
55

66
#include <pas_auth.h>
7+
#include <pas_fuse.h>
78
#include <pas_mbn.h>
89
#include <pas_meta.h>
10+
#include <pas_sig_auth.h>
11+
#include <pta_qcom_fuse.h>
912
#include <pta_qcom_pas.h>
1013
#include <string.h>
14+
#include <string_ext.h>
1115
#include <tee_internal_api.h>
1216
#include <utee_defines.h>
1317

@@ -80,7 +84,9 @@ TEE_Result pas_auth_save_metadata(struct qcom_pas_session *s, uint32_t pt,
8084
TEE_Result pas_auth_prepare(struct qcom_pas_session *s, uint32_t pas_id)
8185
{
8286
struct pas_md_slot *slot = get_meta_data_slot(s, pas_id);
87+
uint8_t anchor[PTA_QCOM_FUSE_ROOT_OF_TRUST_SIZE] = { };
8388
TEE_Result res = TEE_ERROR_GENERIC;
89+
bool secboot_on = false;
8490
uint32_t hash_len = 0;
8591

8692
if (!slot) {
@@ -96,16 +102,37 @@ TEE_Result pas_auth_prepare(struct qcom_pas_session *s, uint32_t pas_id)
96102
return res;
97103
}
98104

105+
res = pas_fuse_get_secboot_and_root_anchor(anchor, &secboot_on);
106+
if (res)
107+
secboot_on = true;
108+
109+
res = pas_sig_auth_hash_len(slot, &hash_len);
110+
if (res) {
111+
EMSG("PAS auth: cannot pick hash size: %#"PRIx32, res);
112+
goto out;
113+
}
114+
99115
res = pas_mbn_parse(slot->meta_data, slot->meta_data_size, hash_len,
100116
&slot->mbn);
101117
if (res) {
102118
EMSG("PAS auth: MBN parse failed: %#"PRIx32, res);
103-
return res;
119+
goto out;
120+
}
121+
122+
if (secboot_on) {
123+
res = pas_sig_auth_authenticate(&slot->mbn, slot->meta_data,
124+
slot->meta_data_size, pas_id,
125+
hash_len, anchor);
126+
if (res)
127+
goto out;
104128
}
105129

106130
slot->ready = true;
131+
res = TEE_SUCCESS;
132+
out:
133+
memzero_explicit(anchor, sizeof(anchor));
107134

108-
return TEE_SUCCESS;
135+
return res;
109136
}
110137

111138
TEE_Result pas_auth_verify(struct qcom_pas_session *s,

ta/qcom_pas/src/auth/pas_policy.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: BSD-2-Clause
2+
/*
3+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
*/
5+
6+
#include <pas_policy.h>
7+
#include <tee_api_types.h>
8+
#include <util.h>
9+
10+
#define PAS_ID_QDSP6 1
11+
#define PAS_ID_WPSS 6
12+
#define PAS_ID_VENUS 9
13+
#define PAS_ID_TURING 18
14+
#define PAS_ID_TURING1 30
15+
#define PAS_ID_CAMERA 33
16+
#define PAS_ID_GPDSP0 39
17+
#define PAS_ID_GPDSP1 40
18+
19+
#define SECBOOT_ADSP_SW_TYPE 0x04
20+
#define SECBOOT_WCNSS_SW_TYPE 0x0D
21+
#define SECBOOT_VIDEO_SW_TYPE 0x0E
22+
#define SECBOOT_CDSP_SW_TYPE 0x17
23+
#define SECBOOT_CAMERA_FW_SW_TYPE 0x34
24+
#define SECBOOT_CDSP1_SW_TYPE 0x44
25+
#define SECBOOT_GPDSP0_SW_TYPE 0x58
26+
#define SECBOOT_GPDSP1_SW_TYPE 0x5A
27+
28+
static const struct {
29+
uint32_t pas_id;
30+
uint32_t swid;
31+
} pas_swid_map[] = {
32+
{ PAS_ID_QDSP6, SECBOOT_ADSP_SW_TYPE },
33+
{ PAS_ID_WPSS, SECBOOT_WCNSS_SW_TYPE },
34+
{ PAS_ID_VENUS, SECBOOT_VIDEO_SW_TYPE },
35+
{ PAS_ID_TURING, SECBOOT_CDSP_SW_TYPE },
36+
{ PAS_ID_TURING1, SECBOOT_CDSP1_SW_TYPE },
37+
{ PAS_ID_CAMERA, SECBOOT_CAMERA_FW_SW_TYPE },
38+
{ PAS_ID_GPDSP0, SECBOOT_GPDSP0_SW_TYPE },
39+
{ PAS_ID_GPDSP1, SECBOOT_GPDSP1_SW_TYPE },
40+
};
41+
42+
TEE_Result pas_policy_expected_swid(uint32_t pas_id, uint32_t *swid)
43+
{
44+
size_t i = 0;
45+
46+
if (!swid)
47+
return TEE_ERROR_BAD_PARAMETERS;
48+
49+
for (i = 0; i < ARRAY_SIZE(pas_swid_map); i++) {
50+
if (pas_swid_map[i].pas_id == pas_id) {
51+
*swid = pas_swid_map[i].swid;
52+
return TEE_SUCCESS;
53+
}
54+
}
55+
56+
return TEE_ERROR_NOT_SUPPORTED;
57+
}

0 commit comments

Comments
 (0)