1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #include <libpldm/oem/meta/file_io.h>
3 #include <endian.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdio.h>
7
8 #include "api.h"
9 #include "msgbuf.h"
10 #include "dsp/base.h"
11
12 LIBPLDM_ABI_STABLE
pldm_oem_meta_file_io_write_req_data(struct pldm_oem_meta_file_io_write_req * req)13 void *pldm_oem_meta_file_io_write_req_data(
14 struct pldm_oem_meta_file_io_write_req *req)
15 {
16 return req->data;
17 }
18
19 LIBPLDM_ABI_STABLE
decode_oem_meta_file_io_write_req(const struct pldm_msg * msg,size_t payload_length,struct pldm_oem_meta_file_io_write_req * req,size_t req_length)20 int decode_oem_meta_file_io_write_req(
21 const struct pldm_msg *msg, size_t payload_length,
22 struct pldm_oem_meta_file_io_write_req *req, size_t req_length)
23 {
24 struct pldm_msgbuf _buf;
25 struct pldm_msgbuf *buf = &_buf;
26 int rc;
27
28 if (msg == NULL || req == NULL) {
29 return -EINVAL;
30 }
31
32 if (req_length < sizeof(*req)) {
33 return -EINVAL;
34 }
35
36 rc = pldm_msgbuf_init_errno(buf,
37 PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH,
38 msg->payload, payload_length);
39 if (rc) {
40 return rc;
41 }
42
43 pldm_msgbuf_extract(buf, req->handle);
44 rc = pldm_msgbuf_extract(buf, req->length);
45 if (rc) {
46 return rc;
47 }
48
49 rc = pldm_msgbuf_extract_array(buf, req->length, req->data,
50 req_length - sizeof(*req));
51 if (rc) {
52 return rc;
53 }
54
55 return pldm_msgbuf_destroy_consumed(buf);
56 }
57
58 LIBPLDM_ABI_DEPRECATED_UNSAFE
decode_oem_meta_file_io_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * file_handle,uint32_t * length,uint8_t * data)59 int decode_oem_meta_file_io_req(const struct pldm_msg *msg,
60 size_t payload_length, uint8_t *file_handle,
61 uint32_t *length, uint8_t *data)
62 {
63 struct pldm_oem_meta_file_io_write_req *request_msg;
64 size_t request_msg_len;
65 int rc;
66
67 if (msg == NULL || file_handle == NULL || length == NULL ||
68 data == NULL) {
69 return pldm_xlate_errno(-EINVAL);
70 }
71
72 if (SIZE_MAX - sizeof(*request_msg) < payload_length) {
73 return pldm_xlate_errno(-EOVERFLOW);
74 }
75
76 request_msg_len = sizeof(*request_msg) + payload_length;
77 request_msg = malloc(request_msg_len);
78
79 rc = decode_oem_meta_file_io_write_req(msg, payload_length, request_msg,
80 request_msg_len);
81 if (rc < 0) {
82 free(request_msg);
83 return pldm_xlate_errno(rc);
84 }
85
86 *file_handle = request_msg->handle;
87 *length = request_msg->length;
88
89 /* NOTE: Unsafe, memory safety is not possible due to API constraints. */
90 memcpy(data, request_msg->data, request_msg->length);
91
92 free(request_msg);
93
94 return 0;
95 }
96
97 LIBPLDM_ABI_STABLE
decode_oem_meta_file_io_read_req(const struct pldm_msg * msg,size_t payload_length,struct pldm_oem_meta_file_io_read_req * req)98 int decode_oem_meta_file_io_read_req(const struct pldm_msg *msg,
99 size_t payload_length,
100 struct pldm_oem_meta_file_io_read_req *req)
101 {
102 struct pldm_msgbuf _buf;
103 struct pldm_msgbuf *buf = &_buf;
104
105 if (msg == NULL || req == NULL) {
106 return -EINVAL;
107 }
108
109 if (req->version > sizeof(struct pldm_oem_meta_file_io_read_req)) {
110 return -E2BIG;
111 }
112
113 int rc = pldm_msgbuf_init_errno(
114 buf, PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH, msg->payload,
115 payload_length);
116 if (rc) {
117 return rc;
118 }
119
120 pldm_msgbuf_extract(buf, req->handle);
121 rc = pldm_msgbuf_extract(buf, req->option);
122 if (rc) {
123 return rc;
124 }
125
126 rc = pldm_msgbuf_extract(buf, req->length);
127 if (rc) {
128 return rc;
129 }
130
131 switch (req->option) {
132 case PLDM_OEM_META_FILE_IO_READ_ATTR:
133 if (req->length != 0) {
134 return -EPROTO;
135 }
136 break;
137 case PLDM_OEM_META_FILE_IO_READ_DATA:
138 pldm_msgbuf_extract(buf, req->info.data.transferFlag);
139 pldm_msgbuf_extract(buf, req->info.data.offset);
140 break;
141 default:
142 return -EPROTO;
143 }
144
145 return pldm_msgbuf_destroy_consumed(buf);
146 }
147
148 LIBPLDM_ABI_STABLE
pldm_oem_meta_file_io_read_resp_data(struct pldm_oem_meta_file_io_read_resp * resp)149 void *pldm_oem_meta_file_io_read_resp_data(
150 struct pldm_oem_meta_file_io_read_resp *resp)
151 {
152 return resp->data;
153 }
154
155 LIBPLDM_ABI_STABLE
encode_oem_meta_file_io_read_resp(uint8_t instance_id,struct pldm_oem_meta_file_io_read_resp * resp,size_t resp_len,struct pldm_msg * responseMsg,size_t payload_length)156 int encode_oem_meta_file_io_read_resp(
157 uint8_t instance_id, struct pldm_oem_meta_file_io_read_resp *resp,
158 size_t resp_len, struct pldm_msg *responseMsg, size_t payload_length)
159 {
160 int rc;
161 struct pldm_msgbuf _buf;
162 struct pldm_msgbuf *buf = &_buf;
163 struct pldm_header_info header = { 0 };
164
165 if (resp == NULL || responseMsg == NULL) {
166 return -EINVAL;
167 }
168
169 if (resp_len < sizeof(*resp)) {
170 return -EINVAL;
171 }
172
173 if (resp->version > sizeof(*resp)) {
174 return -E2BIG;
175 }
176
177 header.instance = instance_id;
178 header.msg_type = PLDM_RESPONSE;
179 header.pldm_type = PLDM_OEM;
180 header.command = PLDM_OEM_META_FILE_IO_CMD_READ_FILE;
181 rc = pack_pldm_header_errno(&header, &(responseMsg->hdr));
182 if (rc) {
183 return rc;
184 }
185
186 rc = pldm_msgbuf_init_errno(buf,
187 PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE,
188 responseMsg->payload, payload_length);
189 if (rc) {
190 return rc;
191 }
192
193 pldm_msgbuf_insert(buf, resp->completion_code);
194 pldm_msgbuf_insert(buf, resp->handle);
195 pldm_msgbuf_insert(buf, resp->option);
196 pldm_msgbuf_insert(buf, resp->length);
197
198 switch (resp->option) {
199 case PLDM_OEM_META_FILE_IO_READ_ATTR:
200 pldm_msgbuf_insert(buf, resp->info.attr.size);
201 pldm_msgbuf_insert(buf, resp->info.attr.crc32);
202 break;
203 case PLDM_OEM_META_FILE_IO_READ_DATA:
204 pldm_msgbuf_insert(buf, resp->info.data.transferFlag);
205 pldm_msgbuf_insert(buf, resp->info.data.offset);
206 rc = pldm_msgbuf_insert_array_uint8(buf, resp->length,
207 resp->data,
208 resp_len - sizeof(*resp));
209 if (rc) {
210 return rc;
211 }
212 break;
213 default:
214 return -EPROTO;
215 }
216
217 return pldm_msgbuf_destroy(buf);
218 }
219