1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2020 Pengutronix, Rouven Czerwinski <entwicklung@pengutronix.de>
4  */
5 
6 #include <caam_blob.h>
7 #include <caam_common.h>
8 #include <caam_hal_ctrl.h>
9 #include <caam_jr.h>
10 #include <caam_trace.h>
11 #include <caam_utils_mem.h>
12 #include <kernel/tee_common_otp.h>
13 #include <mm/core_memprot.h>
14 #include <stdint.h>
15 #include <string.h>
16 #include <tee/cache.h>
17 
18 #define MKVB_SIZE	32
19 
20 static uint8_t stored_key[MKVB_SIZE];
21 static bool mkvb_retrieved;
22 
caam_blob_mkvb_init(vaddr_t baseaddr)23 enum caam_status caam_blob_mkvb_init(vaddr_t baseaddr)
24 {
25 	struct caam_jobctx jobctx = { };
26 	enum caam_status res = CAAM_NO_ERROR;
27 	struct caambuf buf = { };
28 	uint32_t *desc = NULL;
29 
30 	assert(!mkvb_retrieved);
31 
32 	res = caam_calloc_align_buf(&buf, MKVB_SIZE);
33 	if (res != CAAM_NO_ERROR)
34 		goto out;
35 
36 	desc = caam_calloc_desc(8);
37 	if (!desc) {
38 		res = CAAM_OUT_MEMORY;
39 		goto out_buf;
40 	}
41 
42 	caam_desc_init(desc);
43 	caam_desc_add_word(desc, DESC_HEADER(0));
44 	caam_desc_add_word(desc, SEQ_OUT_PTR(32));
45 	caam_desc_add_ptr(desc, buf.paddr);
46 	caam_desc_add_word(desc, BLOB_MSTR_KEY);
47 	BLOB_DUMPDESC(desc);
48 
49 	cache_operation(TEE_CACHEFLUSH, buf.data, buf.length);
50 
51 	jobctx.desc = desc;
52 	res = caam_jr_enqueue(&jobctx, NULL);
53 
54 	if (res != CAAM_NO_ERROR) {
55 		BLOB_TRACE("JR return code: %#"PRIx32, res);
56 		BLOB_TRACE("MKVB failed: Job status %#"PRIx32, jobctx.status);
57 	} else {
58 		cache_operation(TEE_CACHEINVALIDATE, buf.data, MKVB_SIZE);
59 		BLOB_DUMPBUF("MKVB", buf.data, buf.length);
60 		memcpy(&stored_key, buf.data, buf.length);
61 		mkvb_retrieved = true;
62 	}
63 
64 out_buf:
65 	caam_free_desc(&desc);
66 	caam_free_buf(&buf);
67 out:
68 	caam_hal_ctrl_inc_priblob(baseaddr);
69 
70 	return res;
71 }
72 
tee_otp_get_hw_unique_key(struct tee_hw_unique_key * hwkey)73 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
74 {
75 	COMPILE_TIME_ASSERT(sizeof(hwkey->data) <= sizeof(stored_key));
76 
77 	if (!mkvb_retrieved)
78 		return TEE_ERROR_SECURITY;
79 
80 	memcpy(&hwkey->data, &stored_key, sizeof(hwkey->data));
81 	return TEE_SUCCESS;
82 }
83