1 /*
2  * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstring>
9 #include <string>
10 #include <CppUTest/TestHarness.h>
11 #include <service/crypto/protobuf/generate_key.pb.h>
12 #include <service/crypto/protobuf/export_public_key.pb.h>
13 #include <service/crypto/protobuf/sign_hash.pb.h>
14 #include <pb.h>
15 #include <pb_encode.h>
16 #include <pb_decode.h>
17 
18 
TEST_GROUP(CryptoMsgTests)19 TEST_GROUP(CryptoMsgTests) {
20 
21 	void setup() {
22         print_info = false;
23     }
24 
25 	/* Nanopb encode/decode methods */
26 	static bool encode_byte_array(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) {
27 
28 		const pb_bytes_array_t *byte_array = (const pb_bytes_array_t *)*arg;
29 		if (!pb_encode_tag_for_field(stream, field)) return false;
30 
31 		return pb_encode_string(stream, byte_array->bytes, byte_array->size);
32 	}
33 
34 	static bool decode_byte_array(pb_istream_t *stream, const pb_field_t *field, void **arg) {
35 
36 		(void)field;
37 		pb_bytes_array_t *byte_array = (pb_bytes_array_t *)*arg;
38 		if (stream->bytes_left > byte_array->size) return false;
39 
40 		return pb_read(stream, byte_array->bytes, stream->bytes_left);
41 	}
42 
43 	static pb_callback_t out_byte_array(const pb_bytes_array_t *byte_array) {
44 
45 		pb_callback_t callback;
46 		callback.funcs.encode = encode_byte_array;
47 		callback.arg = (void*)byte_array;
48 
49 		return callback;
50 	}
51 
52 	static pb_callback_t in_byte_array(pb_bytes_array_t *byte_array) {
53 
54 		pb_callback_t callback;
55 		callback.funcs.decode = decode_byte_array;
56 		callback.arg = (void*)byte_array;
57 		return callback;
58 	}
59 
60 	bool print_info;
61 };
62 
TEST(CryptoMsgTests,GenerateKeyInMsgTest)63 TEST(CryptoMsgTests, GenerateKeyInMsgTest) {
64 	/* Sender - set values and serialize */
65 	ts_crypto_GenerateKeyIn sent_msg = ts_crypto_GenerateKeyIn_init_default;
66 	ts_crypto_KeyAttributes sent_key_attributes = ts_crypto_KeyAttributes_init_default;
67 
68 	sent_key_attributes.type = ts_crypto_EccCurve_ECC_FAMILY_SECP_R1;
69 
70 	sent_key_attributes.key_bits = 256;
71 	sent_key_attributes.lifetime = ts_crypto_KeyLifetime_KEY_LIFETIME_PERSISTENT;
72 	sent_key_attributes.id = 3;
73 
74 	sent_key_attributes.has_policy = true;
75 	sent_key_attributes.policy.usage = ts_crypto_KeyUsage_KEY_USAGE_SIGN_HASH;
76 	sent_key_attributes.policy.alg = ts_crypto_Alg_ALG_SHA_256;
77 
78 	sent_msg.attributes = sent_key_attributes;
79 	sent_msg.has_attributes = true;
80 
81 	size_t sent_msg_len;
82 	CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_GenerateKeyIn_fields, &sent_msg));
83 	uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len);
84 	CHECK(sent_msg_len > 0);
85 	CHECK(sent_msg_buf);
86 
87 	pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len);
88 	CHECK(pb_encode(&ostream, ts_crypto_GenerateKeyIn_fields, &sent_msg));
89 	CHECK_EQUAL(sent_msg_len, ostream.bytes_written);
90 
91 	/* Receiver - deserialize and use values */
92 	ts_crypto_GenerateKeyIn recv_msg = ts_crypto_GenerateKeyIn_init_default;
93 
94 	pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len);
95 	CHECK_EQUAL(sent_msg_len, istream.bytes_left);
96 	CHECK(pb_decode(&istream, ts_crypto_GenerateKeyIn_fields, &recv_msg));
97 	CHECK_EQUAL(0, istream.bytes_left);
98 
99 	free(sent_msg_buf);
100 
101 	CHECK(recv_msg.has_attributes);
102 	CHECK_EQUAL(sent_key_attributes.type, recv_msg.attributes.type);
103 	CHECK_EQUAL(sent_key_attributes.key_bits, recv_msg.attributes.key_bits);
104 	CHECK_EQUAL(sent_key_attributes.lifetime, recv_msg.attributes.lifetime);
105 	CHECK_EQUAL(sent_key_attributes.id, recv_msg.attributes.id);
106 
107 	CHECK(recv_msg.attributes.has_policy);
108 	CHECK_EQUAL(sent_key_attributes.policy.usage, recv_msg.attributes.policy.usage);
109 	CHECK_EQUAL(sent_key_attributes.policy.alg, recv_msg.attributes.policy.alg);
110 
111 	if (print_info) {
112 		printf("Serialized op_export_public_key len: %ld\n", sent_msg_len);
113 	}
114 }
115 
TEST(CryptoMsgTests,ExportPublicKeyInMsgTest)116 TEST(CryptoMsgTests, ExportPublicKeyInMsgTest) {
117 	/* Sender - set values and serialize */
118 	ts_crypto_ExportPublicKeyIn sent_msg = ts_crypto_ExportPublicKeyIn_init_default;
119 
120 	sent_msg.id = 55;
121 
122 	size_t sent_msg_len;
123 	CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_ExportPublicKeyIn_fields, &sent_msg));
124 	uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len);
125 	CHECK(sent_msg_len > 0);
126 	CHECK(sent_msg_buf);
127 
128 	pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len);
129 	CHECK(pb_encode(&ostream, ts_crypto_ExportPublicKeyIn_fields, &sent_msg));
130 	CHECK_EQUAL(sent_msg_len, ostream.bytes_written);
131 
132 	/* Receiver - deserialize and use values */
133 	ts_crypto_ExportPublicKeyIn recv_msg = ts_crypto_ExportPublicKeyIn_init_default;
134 
135 	pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len);
136 	CHECK_EQUAL(sent_msg_len, istream.bytes_left);
137 	CHECK(pb_decode(&istream, ts_crypto_ExportPublicKeyIn_fields, &recv_msg));
138 	CHECK_EQUAL(0, istream.bytes_left);
139 
140 	CHECK_EQUAL(sent_msg.id, recv_msg.id);
141 
142 	free(sent_msg_buf);
143 
144 	if (print_info) {
145 		printf("Serialized op_export_public_key len: %ld\n", sent_msg_len);
146 	}
147 }
148 
TEST(CryptoMsgTests,ExportPublicKeyOutMsgTest)149 TEST(CryptoMsgTests, ExportPublicKeyOutMsgTest) {
150 	/* Sender - set values and serialize */
151 	ts_crypto_ExportPublicKeyOut sent_msg = ts_crypto_ExportPublicKeyOut_init_default;
152 
153 	PB_BYTES_ARRAY_T(5) example_key = {5, {0x31, 0x32, 0x33, 0x34, 0x35}};
154 	sent_msg.data = out_byte_array((const pb_bytes_array_t *)&example_key);
155 
156 	size_t sent_msg_len;
157 	CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_ExportPublicKeyOut_fields, &sent_msg));
158 	uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len);
159 	CHECK(sent_msg_len > 0);
160 	CHECK(sent_msg_buf);
161 
162 	pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len);
163 	CHECK(pb_encode(&ostream, ts_crypto_ExportPublicKeyOut_fields, &sent_msg));
164 	CHECK_EQUAL(sent_msg_len, ostream.bytes_written);
165 
166 	/* Receiver - deserialize and use values */
167 	PB_BYTES_ARRAY_T(5) recv_key = {5, {0}};
168 	ts_crypto_ExportPublicKeyOut recv_msg = ts_crypto_ExportPublicKeyOut_init_default;
169 	recv_msg.data = in_byte_array((pb_bytes_array_t *)&recv_key);
170 
171 	pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len);
172 	CHECK_EQUAL(sent_msg_len, istream.bytes_left);
173 	CHECK(pb_decode(&istream, ts_crypto_ExportPublicKeyOut_fields, &recv_msg));
174 	CHECK_EQUAL(0, istream.bytes_left);
175 
176 	free(sent_msg_buf);
177 
178 	CHECK_EQUAL(example_key.size, recv_key.size);
179 	CHECK(memcmp(example_key.bytes, recv_key.bytes, example_key.size) == 0);
180 
181 	if (print_info) {
182 		printf("Serialized result_export_public_key len: %ld\n", sent_msg_len);
183 	}
184 }
185 
TEST(CryptoMsgTests,SignHashInMsgTest)186 TEST(CryptoMsgTests, SignHashInMsgTest) {
187 	/* Sender - set values and serialize */
188 	ts_crypto_SignHashIn sent_msg = ts_crypto_SignHashIn_init_default;
189 
190 	PB_BYTES_ARRAY_T(6) msg_to_sign = {6, {0x34, 0x32, 0x33, 0x34, 0x35, 0x36}};
191 	sent_msg.hash = out_byte_array((const pb_bytes_array_t *)&msg_to_sign);
192 
193 	sent_msg.id = 71;
194 	sent_msg.alg = ts_crypto_Alg_ALG_SHA_256;
195 
196 	size_t sent_msg_len;
197 	CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_SignHashIn_fields, &sent_msg));
198 	uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len);
199 	CHECK(sent_msg_len > 0);
200 	CHECK(sent_msg_buf);
201 
202 	pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len);
203 	CHECK(pb_encode(&ostream, ts_crypto_SignHashIn_fields, &sent_msg));
204 	CHECK_EQUAL(sent_msg_len, ostream.bytes_written);
205 
206 	/* Receiver - deserialize and use values */
207 	PB_BYTES_ARRAY_T(6) recv_msg_to_sign = {6, {0}};
208 	ts_crypto_SignHashIn recv_msg = ts_crypto_SignHashIn_init_default;
209 	recv_msg.hash = in_byte_array((pb_bytes_array_t *)&recv_msg_to_sign);
210 
211 	pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len);
212 	CHECK_EQUAL(sent_msg_len, istream.bytes_left);
213 	CHECK(pb_decode(&istream, ts_crypto_SignHashIn_fields, &recv_msg));
214 	CHECK_EQUAL(0, istream.bytes_left);
215 
216 	free(sent_msg_buf);
217 
218 	CHECK_EQUAL(sent_msg.id, recv_msg.id);
219 	CHECK_EQUAL(sent_msg.alg, recv_msg.alg);
220 
221 	CHECK_EQUAL(msg_to_sign.size, recv_msg_to_sign.size);
222 	CHECK(memcmp(msg_to_sign.bytes, recv_msg_to_sign.bytes, msg_to_sign.size) == 0);
223 
224 	if (print_info) {
225 		printf("Serialized op_asym_sign len: %ld\n", sent_msg_len);
226 	}
227 }
228 
TEST(CryptoMsgTests,SignHashOutMsgTest)229 TEST(CryptoMsgTests, SignHashOutMsgTest) {
230 	/* Sender - set values and serialize */
231 	ts_crypto_SignHashOut sent_msg = ts_crypto_SignHashOut_init_default;
232 
233 	PB_BYTES_ARRAY_T(10) example_signature = {10, {0x01, 0x02, 0x5a, 0x7c, 0x35, 0x01, 0x02, 0x5a, 0x7c, 0x35}};
234 	sent_msg.signature = out_byte_array((const pb_bytes_array_t *)&example_signature);
235 
236 	size_t sent_msg_len;
237 	CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_SignHashOut_fields, &sent_msg));
238 	uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len);
239 	CHECK(sent_msg_len > 0);
240 	CHECK(sent_msg_buf);
241 
242 	pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len);
243 	CHECK(pb_encode(&ostream, ts_crypto_SignHashOut_fields, &sent_msg));
244 	CHECK_EQUAL(sent_msg_len, ostream.bytes_written);
245 
246 	/* Receiver - deserialize and use values */
247 	PB_BYTES_ARRAY_T(10) recv_signature = {10, {0}};
248 	ts_crypto_SignHashOut recv_msg = ts_crypto_SignHashOut_init_default;
249 	recv_msg.signature = in_byte_array((pb_bytes_array_t *)&recv_signature);
250 
251 	pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len);
252 	CHECK_EQUAL(sent_msg_len, istream.bytes_left);
253 	CHECK(pb_decode(&istream, ts_crypto_SignHashOut_fields, &recv_msg));
254 	CHECK_EQUAL(0, istream.bytes_left);
255 
256 	free(sent_msg_buf);
257 
258 	CHECK_EQUAL(example_signature.size, recv_signature.size);
259 	CHECK(memcmp(example_signature.bytes, recv_signature.bytes, example_signature.size) == 0);
260 
261 	if (print_info) {
262 		printf("Serialized result_asym_sign len: %ld\n", sent_msg_len);
263 	}
264 }
265