blob: e4eb8cee86606cc3ad194ae9fc896ae09ecf9029 [file] [log] [blame]
Imre Kis23d1ba52023-10-20 13:56:47 +02001/*
2 * Copyright (c) 2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef RPMB_FRONTEND_H_
8#define RPMB_FRONTEND_H_
9
10#include "components/service/rpmb/backend/rpmb_backend.h"
11#include "components/rpc/common/caller/rpc_caller_session.h"
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
17/**
18 * \brief RPMB platform interface
19 *
20 * It the interface for the necessary platform dependent functions:
21 * * deriving RPMB key from hardware unique key
22 * * get random nonce value
23 * * calculate RPMB MAC value
24 */
25struct rpmb_platform_interface {
26 /**
27 * \brief Device key from hardware unique key for creating the RPMB authentication key
28 *
29 * \param context[in] Platform context
30 * \param data[in] Key derivation data (i.e. salt)
31 * \param data_length[in] Key derivation data length
32 * \param key[out] Derived authentication key
33 * \param key_length[in] Required authentication key length
34 * \return psa_status_t
35 */
36 psa_status_t (*derive_key)(void *context, const uint8_t *data, size_t data_length,
37 uint8_t *key, size_t key_length);
38
39 /**
40 * \brief Get random nonce value
41 *
42 * \param context[in] Platform context
43 * \param nonce[out] Generated nonce value
44 * \param nonce_length[in] Nonce length
45 * \return psa_status_t
46 */
47 psa_status_t (*get_nonce)(void *context, uint8_t *nonce, size_t nonce_length);
48
49 /**
50 * \brief Calculate MAC field value
51 *
52 * \param context[in] Platform context
53 * \param key[in] Authentication key
54 * \param key_length[in] Authentication key length
55 * \param frames[in] Data frames
56 * \param frame_count[in] Data frame count
57 * \param mac[out] Calculated MAC value
58 * \param mac_length[in] MAC value length
59 * \return psa_status_t
60 */
61 psa_status_t (*calculate_mac)(void *context, const uint8_t *key, size_t key_length,
62 const struct rpmb_data_frame *frames, size_t frame_count,
63 uint8_t *mac, size_t mac_length);
64};
65
66/**
67 * \brief RPMB platform
68 *
69 * Generic object for storing the RPMB platform interface and the implementation specific context.
70 */
71struct rpmb_platform {
72 void *context;
73 struct rpmb_platform_interface *interface;
74};
75
76/**
77 * \brief RPMB frontend
78 *
79 * The RPMB frontend provides a high level read/write interface for accessing
80 * the RPMB device and it does calls to the RPMB backend. This component
81 * contains the main RPMB logic, including:
82 * * Writing authentication key
83 * * Handling the write counter
84 * * Building and verifying RPMB data frames
85 */
86struct rpmb_frontend {
87 struct rpmb_platform *platform;
88 struct rpmb_backend *backend;
89 uint32_t dev_id;
90 bool initialized;
91 size_t block_count;
92 uint8_t key[RPMB_KEY_MAC_SIZE];
93 uint32_t write_counter;
94};
95
96/**
97 * \brief Create RPMB frontend
98 *
99 * This function only initializes the internal objects. It doesn't require the backend to be able
100 * to access the RPMB hardware.
101 *
102 * \param context[in] RPMB frontend context
103 * \param platform[in] RPMB platform
104 * \param backend[in] RPMB backend
105 * \param dev_id[in] Device ID
106 * \return psa_status_t
107 */
108psa_status_t rpmb_frontend_create(struct rpmb_frontend *context, struct rpmb_platform *platform,
109 struct rpmb_backend *backend, uint32_t dev_id);
110
111/**
112 * \brief Init RPMB frontend
113 *
114 * This function requires access to the RPMB hardware via the backend. It reads derives the
115 * authentication key, reads the write counter and possibly writes the authentication key.
116 *
117 * \param context[in] RPMB frontend context
118 * \return psa_status_t
119 */
120psa_status_t rpmb_frontend_init(struct rpmb_frontend *context);
121
122/**
123 * \brief Destroy RPMB frontend
124 *
125 * \param context[in] RPMB frontend context
126 */
127void rpmb_frontend_destroy(struct rpmb_frontend *context);
128
129/**
130 * \brief Query RPMB block size
131 *
132 * \param context[in] RPMB frontend context
133 * \param block_size[out] Block size in bytes
134 * \return psa_status_t
135 */
136psa_status_t rpmb_frontend_block_size(struct rpmb_frontend *context, size_t *block_size);
137
138/**
139 * \brief Query RPMB block count
140 *
141 * \param context[in] RPMB frontend context
142 * \param block_count[out] Block count
143 * \return psa_status_t
144 */
145psa_status_t rpmb_frontend_block_count(struct rpmb_frontend *context, size_t *block_count);
146
147/**
148 * \brief Write complete blocks to RPMB
149 *
150 * \param context[in] RPMB frontend context
151 * \param block_index[in] Block index
152 * \param data[in] Data, its size must be [block count] * [block size]
153 * \param block_count[in] Block count
154 * \return psa_status_t
155 */
156psa_status_t rpmb_frontend_write(struct rpmb_frontend *context, uint16_t block_index,
157 const uint8_t *data, size_t block_count);
158
159/**
160 * \brief Read complete blocks from RPMB
161 *
162 * \param context[in] RPMB frontend context
163 * \param block_index[in] Block index
164 * \param data[out] Data, its size must be [block count] * [block size]
165 * \param block_count[in] Block count
166 * \return psa_status_t
167 */
168psa_status_t rpmb_frontend_read(struct rpmb_frontend *context, uint16_t block_index,
169 uint8_t *data, size_t block_count);
170
171#ifdef __cplusplus
172}
173#endif
174
175#endif /* RPMB_CLIENT_H_ */