1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include <trusty/keymaster_serializable.h>
26 
append_to_buf(uint8_t * buf,const void * data,size_t data_len)27 uint8_t* append_to_buf(uint8_t* buf, const void* data, size_t data_len) {
28     if (data && data_len) {
29         trusty_memcpy(buf, data, data_len);
30     }
31     return buf + data_len;
32 }
33 
append_uint32_to_buf(uint8_t * buf,uint32_t val)34 uint8_t* append_uint32_to_buf(uint8_t* buf, uint32_t val) {
35     return append_to_buf(buf, &val, sizeof(val));
36 }
37 
append_sized_buf_to_buf(uint8_t * buf,const uint8_t * data,uint32_t data_len)38 uint8_t* append_sized_buf_to_buf(uint8_t* buf,
39                                  const uint8_t* data,
40                                  uint32_t data_len) {
41     buf = append_uint32_to_buf(buf, data_len);
42     return append_to_buf(buf, data, data_len);
43 }
44 
km_boot_params_serialize(const struct km_boot_params * params,uint8_t ** out,uint32_t * out_size)45 int km_boot_params_serialize(const struct km_boot_params* params,
46                              uint8_t** out,
47                              uint32_t* out_size) {
48     uint8_t* tmp;
49 
50     if (!out || !params || !out_size) {
51         return TRUSTY_ERR_INVALID_ARGS;
52     }
53     *out_size = (sizeof(params->os_version) + sizeof(params->os_patchlevel) +
54                  sizeof(params->device_locked) +
55                  sizeof(params->verified_boot_state) +
56                  sizeof(params->verified_boot_key_hash_size) +
57                  sizeof(params->verified_boot_hash_size) +
58                  params->verified_boot_key_hash_size +
59                  params->verified_boot_hash_size);
60     *out = trusty_calloc(*out_size, 1);
61     if (!*out) {
62         return TRUSTY_ERR_NO_MEMORY;
63     }
64 
65     tmp = append_uint32_to_buf(*out, params->os_version);
66     tmp = append_uint32_to_buf(tmp, params->os_patchlevel);
67     tmp = append_uint32_to_buf(tmp, params->device_locked);
68     tmp = append_uint32_to_buf(tmp, params->verified_boot_state);
69     tmp = append_sized_buf_to_buf(tmp, params->verified_boot_key_hash,
70                                   params->verified_boot_key_hash_size);
71     tmp = append_sized_buf_to_buf(tmp, params->verified_boot_hash,
72                                   params->verified_boot_hash_size);
73 
74     return TRUSTY_ERR_NONE;
75 }
76 
km_attestation_data_serialize(const struct km_attestation_data * data,uint8_t ** out,uint32_t * out_size)77 int km_attestation_data_serialize(const struct km_attestation_data* data,
78                                   uint8_t** out,
79                                   uint32_t* out_size) {
80     uint8_t* tmp;
81 
82     if (!out || !data || !out_size) {
83         return TRUSTY_ERR_INVALID_ARGS;
84     }
85     *out_size = (sizeof(data->algorithm) + sizeof(data->data_size) +
86                  data->data_size);
87     *out = trusty_calloc(*out_size, 1);
88     if (!*out) {
89         return TRUSTY_ERR_NO_MEMORY;
90     }
91 
92     tmp = append_uint32_to_buf(*out, data->algorithm);
93     tmp = append_sized_buf_to_buf(tmp, data->data, data->data_size);
94 
95     return TRUSTY_ERR_NONE;
96 }
97 
km_raw_buffer_serialize(const struct km_raw_buffer * buf,uint8_t ** out,uint32_t * out_size)98 int km_raw_buffer_serialize(const struct km_raw_buffer* buf,
99                             uint8_t** out,
100                             uint32_t* out_size) {
101     if (!out || !buf || !out_size) {
102         return TRUSTY_ERR_INVALID_ARGS;
103     }
104     *out_size = sizeof(buf->data_size) + buf->data_size;
105     *out = trusty_calloc(*out_size, 1);
106     if (!*out) {
107         return TRUSTY_ERR_NO_MEMORY;
108     }
109     append_sized_buf_to_buf(*out, buf->data, buf->data_size);
110 
111     return TRUSTY_ERR_NONE;
112 }
113