1/*
2 * Copyright 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <keymaster/android_keymaster_messages.h>
18#include <keymaster/android_keymaster_utils.h>
19
20namespace keymaster {
21
22/*
23 * Helper functions for working with key blobs.
24 */
25
26static void set_key_blob(keymaster_key_blob_t* key_blob, const void* key_material, size_t length) {
27    delete[] key_blob->key_material;
28    key_blob->key_material = dup_buffer(key_material, length);
29    key_blob->key_material_size = length;
30}
31
32static size_t key_blob_size(const keymaster_key_blob_t& key_blob) {
33    return sizeof(uint32_t) /* key size */ + key_blob.key_material_size;
34}
35
36static uint8_t* serialize_key_blob(const keymaster_key_blob_t& key_blob, uint8_t* buf,
37                                   const uint8_t* end) {
38    return append_size_and_data_to_buf(buf, end, key_blob.key_material, key_blob.key_material_size);
39}
40
41static bool deserialize_key_blob(keymaster_key_blob_t* key_blob, const uint8_t** buf_ptr,
42                                 const uint8_t* end) {
43    delete[] key_blob->key_material;
44    key_blob->key_material = 0;
45    UniquePtr<uint8_t[]> deserialized_key_material;
46    if (!copy_size_and_data_from_buf(buf_ptr, end, &key_blob->key_material_size,
47                                     &deserialized_key_material))
48        return false;
49    key_blob->key_material = deserialized_key_material.release();
50    return true;
51}
52
53size_t KeymasterResponse::SerializedSize() const {
54    if (error != KM_ERROR_OK)
55        return sizeof(int32_t);
56    else
57        return sizeof(int32_t) + NonErrorSerializedSize();
58}
59
60uint8_t* KeymasterResponse::Serialize(uint8_t* buf, const uint8_t* end) const {
61    buf = append_uint32_to_buf(buf, end, static_cast<uint32_t>(error));
62    if (error == KM_ERROR_OK)
63        buf = NonErrorSerialize(buf, end);
64    return buf;
65}
66
67bool KeymasterResponse::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
68    if (!copy_uint32_from_buf(buf_ptr, end, &error))
69        return false;
70    if (error != KM_ERROR_OK)
71        return true;
72    return NonErrorDeserialize(buf_ptr, end);
73}
74
75GenerateKeyResponse::~GenerateKeyResponse() {
76    delete[] key_blob.key_material;
77}
78
79size_t GenerateKeyResponse::NonErrorSerializedSize() const {
80    return key_blob_size(key_blob) + enforced.SerializedSize() + unenforced.SerializedSize();
81}
82
83uint8_t* GenerateKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
84    buf = serialize_key_blob(key_blob, buf, end);
85    buf = enforced.Serialize(buf, end);
86    return unenforced.Serialize(buf, end);
87}
88
89bool GenerateKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
90    return deserialize_key_blob(&key_blob, buf_ptr, end) && enforced.Deserialize(buf_ptr, end) &&
91           unenforced.Deserialize(buf_ptr, end);
92}
93
94GetKeyCharacteristicsRequest::~GetKeyCharacteristicsRequest() {
95    delete[] key_blob.key_material;
96}
97
98void GetKeyCharacteristicsRequest::SetKeyMaterial(const void* key_material, size_t length) {
99    set_key_blob(&key_blob, key_material, length);
100}
101
102size_t GetKeyCharacteristicsRequest::SerializedSize() const {
103    return key_blob_size(key_blob) + additional_params.SerializedSize();
104}
105
106uint8_t* GetKeyCharacteristicsRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
107    buf = serialize_key_blob(key_blob, buf, end);
108    return additional_params.Serialize(buf, end);
109}
110
111bool GetKeyCharacteristicsRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
112    return deserialize_key_blob(&key_blob, buf_ptr, end) &&
113           additional_params.Deserialize(buf_ptr, end);
114}
115
116size_t GetKeyCharacteristicsResponse::NonErrorSerializedSize() const {
117    return enforced.SerializedSize() + unenforced.SerializedSize();
118}
119
120uint8_t* GetKeyCharacteristicsResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
121    buf = enforced.Serialize(buf, end);
122    return unenforced.Serialize(buf, end);
123}
124
125bool GetKeyCharacteristicsResponse::NonErrorDeserialize(const uint8_t** buf_ptr,
126                                                        const uint8_t* end) {
127    return enforced.Deserialize(buf_ptr, end) && unenforced.Deserialize(buf_ptr, end);
128}
129
130void BeginOperationRequest::SetKeyMaterial(const void* key_material, size_t length) {
131    set_key_blob(&key_blob, key_material, length);
132}
133
134size_t BeginOperationRequest::SerializedSize() const {
135    return sizeof(uint32_t) /* purpose */ + key_blob_size(key_blob) +
136           additional_params.SerializedSize();
137}
138
139uint8_t* BeginOperationRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
140    buf = append_uint32_to_buf(buf, end, purpose);
141    buf = serialize_key_blob(key_blob, buf, end);
142    return additional_params.Serialize(buf, end);
143}
144
145bool BeginOperationRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
146    return copy_uint32_from_buf(buf_ptr, end, &purpose) &&
147           deserialize_key_blob(&key_blob, buf_ptr, end) &&
148           additional_params.Deserialize(buf_ptr, end);
149}
150
151size_t BeginOperationResponse::NonErrorSerializedSize() const {
152    if (message_version == 0)
153        return sizeof(op_handle);
154    else
155        return sizeof(op_handle) + output_params.SerializedSize();
156}
157
158uint8_t* BeginOperationResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
159    buf = append_uint64_to_buf(buf, end, op_handle);
160    if (message_version > 0)
161        buf = output_params.Serialize(buf, end);
162    return buf;
163}
164
165bool BeginOperationResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
166    bool retval = copy_uint64_from_buf(buf_ptr, end, &op_handle);
167    if (retval && message_version > 0)
168        retval = output_params.Deserialize(buf_ptr, end);
169    return retval;
170}
171
172size_t UpdateOperationRequest::SerializedSize() const {
173    if (message_version == 0)
174        return sizeof(op_handle) + input.SerializedSize();
175    else
176        return sizeof(op_handle) + input.SerializedSize() + additional_params.SerializedSize();
177}
178
179uint8_t* UpdateOperationRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
180    buf = append_uint64_to_buf(buf, end, op_handle);
181    buf = input.Serialize(buf, end);
182    if (message_version > 0)
183        buf = additional_params.Serialize(buf, end);
184    return buf;
185}
186
187bool UpdateOperationRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
188    bool retval = copy_uint64_from_buf(buf_ptr, end, &op_handle) && input.Deserialize(buf_ptr, end);
189    if (retval && message_version > 0)
190        retval = additional_params.Deserialize(buf_ptr, end);
191    return retval;
192}
193
194size_t UpdateOperationResponse::NonErrorSerializedSize() const {
195    size_t size = 0;
196    switch (message_version) {
197    case 3:
198    case 2:
199        size += output_params.SerializedSize();
200        ; /* falls through */
201    case 1:
202        size += sizeof(uint32_t);
203        ; /* falls through */
204    case 0:
205        size += output.SerializedSize();
206        break;
207
208    default:
209        assert(false);
210    }
211
212    return size;
213}
214
215uint8_t* UpdateOperationResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
216    buf = output.Serialize(buf, end);
217    if (message_version > 0)
218        buf = append_uint32_to_buf(buf, end, input_consumed);
219    if (message_version > 1)
220        buf = output_params.Serialize(buf, end);
221    return buf;
222}
223
224bool UpdateOperationResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
225    bool retval = output.Deserialize(buf_ptr, end);
226    if (retval && message_version > 0)
227        retval = copy_uint32_from_buf(buf_ptr, end, &input_consumed);
228    if (retval && message_version > 1)
229        retval = output_params.Deserialize(buf_ptr, end);
230    return retval;
231}
232
233size_t FinishOperationRequest::SerializedSize() const {
234    size_t size = 0;
235    switch (message_version) {
236    case 3:
237        size += input.SerializedSize();
238        ; /* falls through */
239    case 2:
240    case 1:
241        size += additional_params.SerializedSize();
242        ; /* falls through */
243    case 0:
244        size += sizeof(op_handle) + signature.SerializedSize();
245        break;
246
247    default:
248        assert(false);  // Should never get here.
249    }
250
251    return size;
252}
253
254uint8_t* FinishOperationRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
255    buf = append_uint64_to_buf(buf, end, op_handle);
256    buf = signature.Serialize(buf, end);
257    if (message_version > 0)
258        buf = additional_params.Serialize(buf, end);
259    if (message_version > 2)
260        buf = input.Serialize(buf, end);
261    return buf;
262}
263
264bool FinishOperationRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
265    bool retval =
266        copy_uint64_from_buf(buf_ptr, end, &op_handle) && signature.Deserialize(buf_ptr, end);
267    if (retval && message_version > 0)
268        retval = additional_params.Deserialize(buf_ptr, end);
269    if (retval && message_version > 2)
270        retval = input.Deserialize(buf_ptr, end);
271    return retval;
272}
273
274size_t FinishOperationResponse::NonErrorSerializedSize() const {
275    if (message_version < 2)
276        return output.SerializedSize();
277    else
278        return output.SerializedSize() + output_params.SerializedSize();
279}
280
281uint8_t* FinishOperationResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
282    buf = output.Serialize(buf, end);
283    if (message_version > 1)
284        buf = output_params.Serialize(buf, end);
285    return buf;
286}
287
288bool FinishOperationResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
289    bool retval = output.Deserialize(buf_ptr, end);
290    if (retval && message_version > 1)
291        retval = output_params.Deserialize(buf_ptr, end);
292    return retval;
293}
294
295size_t AddEntropyRequest::SerializedSize() const {
296    return random_data.SerializedSize();
297}
298
299uint8_t* AddEntropyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
300    return random_data.Serialize(buf, end);
301}
302
303bool AddEntropyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
304    return random_data.Deserialize(buf_ptr, end);
305}
306
307void ImportKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
308    delete[] key_data;
309    key_data = dup_buffer(key_material, length);
310    key_data_length = length;
311}
312
313size_t ImportKeyRequest::SerializedSize() const {
314    return key_description.SerializedSize() + sizeof(uint32_t) /* key_format */ +
315           sizeof(uint32_t) /* key_data_length */ + key_data_length;
316}
317
318uint8_t* ImportKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
319    buf = key_description.Serialize(buf, end);
320    buf = append_uint32_to_buf(buf, end, key_format);
321    return append_size_and_data_to_buf(buf, end, key_data, key_data_length);
322}
323
324bool ImportKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
325    delete[] key_data;
326    key_data = NULL;
327    UniquePtr<uint8_t[]> deserialized_key_material;
328    if (!key_description.Deserialize(buf_ptr, end) ||
329        !copy_uint32_from_buf(buf_ptr, end, &key_format) ||
330        !copy_size_and_data_from_buf(buf_ptr, end, &key_data_length, &deserialized_key_material))
331        return false;
332    key_data = deserialized_key_material.release();
333    return true;
334}
335
336void ImportKeyResponse::SetKeyMaterial(const void* key_material, size_t length) {
337    set_key_blob(&key_blob, key_material, length);
338}
339
340size_t ImportKeyResponse::NonErrorSerializedSize() const {
341    return key_blob_size(key_blob) + enforced.SerializedSize() + unenforced.SerializedSize();
342}
343
344uint8_t* ImportKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
345    buf = serialize_key_blob(key_blob, buf, end);
346    buf = enforced.Serialize(buf, end);
347    return unenforced.Serialize(buf, end);
348}
349
350bool ImportKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
351    return deserialize_key_blob(&key_blob, buf_ptr, end) && enforced.Deserialize(buf_ptr, end) &&
352           unenforced.Deserialize(buf_ptr, end);
353}
354
355void ExportKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
356    set_key_blob(&key_blob, key_material, length);
357}
358
359size_t ExportKeyRequest::SerializedSize() const {
360    return additional_params.SerializedSize() + sizeof(uint32_t) /* key_format */ +
361           key_blob_size(key_blob);
362}
363
364uint8_t* ExportKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
365    buf = additional_params.Serialize(buf, end);
366    buf = append_uint32_to_buf(buf, end, key_format);
367    return serialize_key_blob(key_blob, buf, end);
368}
369
370bool ExportKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
371    return additional_params.Deserialize(buf_ptr, end) &&
372           copy_uint32_from_buf(buf_ptr, end, &key_format) &&
373           deserialize_key_blob(&key_blob, buf_ptr, end);
374}
375
376void ExportKeyResponse::SetKeyMaterial(const void* key_material, size_t length) {
377    delete[] key_data;
378    key_data = dup_buffer(key_material, length);
379    key_data_length = length;
380}
381
382size_t ExportKeyResponse::NonErrorSerializedSize() const {
383    return sizeof(uint32_t) /* key_data_length */ + key_data_length;
384}
385
386uint8_t* ExportKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
387    return append_size_and_data_to_buf(buf, end, key_data, key_data_length);
388}
389
390bool ExportKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
391    delete[] key_data;
392    key_data = NULL;
393    UniquePtr<uint8_t[]> deserialized_key_material;
394    if (!copy_size_and_data_from_buf(buf_ptr, end, &key_data_length, &deserialized_key_material))
395        return false;
396    key_data = deserialized_key_material.release();
397    return true;
398}
399
400void DeleteKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
401    set_key_blob(&key_blob, key_material, length);
402}
403
404size_t DeleteKeyRequest::SerializedSize() const {
405    return key_blob_size(key_blob);
406}
407
408uint8_t* DeleteKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
409    return serialize_key_blob(key_blob, buf, end);
410}
411
412bool DeleteKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
413    return deserialize_key_blob(&key_blob, buf_ptr, end);
414}
415
416size_t GetVersionResponse::NonErrorSerializedSize() const {
417    return sizeof(major_ver) + sizeof(minor_ver) + sizeof(subminor_ver);
418}
419
420uint8_t* GetVersionResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
421    if (buf + NonErrorSerializedSize() <= end) {
422        *buf++ = major_ver;
423        *buf++ = minor_ver;
424        *buf++ = subminor_ver;
425    } else {
426        buf += NonErrorSerializedSize();
427    }
428    return buf;
429}
430
431bool GetVersionResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
432    if (*buf_ptr + NonErrorSerializedSize() > end)
433        return false;
434    const uint8_t* tmp = *buf_ptr;
435    major_ver = *tmp++;
436    minor_ver = *tmp++;
437    subminor_ver = *tmp++;
438    *buf_ptr = tmp;
439    return true;
440}
441
442AttestKeyRequest::~AttestKeyRequest() {
443    delete[] key_blob.key_material;
444}
445
446void AttestKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
447    set_key_blob(&key_blob, key_material, length);
448}
449
450size_t AttestKeyRequest::SerializedSize() const {
451    return key_blob_size(key_blob) + attest_params.SerializedSize();
452}
453
454uint8_t* AttestKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
455    buf = serialize_key_blob(key_blob, buf, end);
456    return attest_params.Serialize(buf, end);
457}
458
459bool AttestKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
460    return deserialize_key_blob(&key_blob, buf_ptr, end) && attest_params.Deserialize(buf_ptr, end);
461}
462
463AttestKeyResponse::~AttestKeyResponse() {
464    for (size_t i = 0; i < certificate_chain.entry_count; ++i)
465        delete[] certificate_chain.entries[i].data;
466    delete[] certificate_chain.entries;
467}
468
469const size_t kMaxChainEntryCount = 10;
470bool AttestKeyResponse::AllocateChain(size_t entry_count) {
471    if (entry_count > kMaxChainEntryCount)
472        return false;
473
474    if (certificate_chain.entries) {
475        for (size_t i = 0; i < certificate_chain.entry_count; ++i)
476            delete[] certificate_chain.entries[i].data;
477        delete[] certificate_chain.entries;
478    }
479
480    certificate_chain.entry_count = entry_count;
481    certificate_chain.entries = new keymaster_blob_t[entry_count];
482    if (!certificate_chain.entries) {
483        certificate_chain.entry_count = 0;
484        return false;
485    }
486
487    memset(certificate_chain.entries, 0, sizeof(certificate_chain.entries[0]) * entry_count);
488    return true;
489}
490
491size_t AttestKeyResponse::NonErrorSerializedSize() const {
492    size_t result = sizeof(uint32_t); /* certificate_chain.entry_count */
493    for (size_t i = 0; i < certificate_chain.entry_count; ++i) {
494        result += sizeof(uint32_t); /* certificate_chain.entries[i].data_length */
495        result += certificate_chain.entries[i].data_length;
496    }
497    return result;
498}
499
500uint8_t* AttestKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
501    buf = append_uint32_to_buf(buf, end, certificate_chain.entry_count);
502    for (size_t i = 0; i < certificate_chain.entry_count; ++i) {
503        buf = append_size_and_data_to_buf(buf, end, certificate_chain.entries[i].data,
504                                          certificate_chain.entries[i].data_length);
505    }
506    return buf;
507}
508
509bool AttestKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
510    size_t entry_count;
511    if (!copy_uint32_from_buf(buf_ptr, end, &entry_count) || !AllocateChain(entry_count))
512        return false;
513
514    for (size_t i = 0; i < certificate_chain.entry_count; ++i) {
515        UniquePtr<uint8_t[]> data;
516        size_t data_length;
517        if (!copy_size_and_data_from_buf(buf_ptr, end, &data_length, &data))
518            return false;
519        certificate_chain.entries[i].data = data.release();
520        certificate_chain.entries[i].data_length = data_length;
521    }
522
523    return true;
524}
525
526UpgradeKeyRequest::~UpgradeKeyRequest() {
527    delete[] key_blob.key_material;
528}
529
530void UpgradeKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
531    set_key_blob(&key_blob, key_material, length);
532}
533
534size_t UpgradeKeyRequest::SerializedSize() const {
535    return key_blob_size(key_blob) + upgrade_params.SerializedSize();
536}
537
538uint8_t* UpgradeKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
539    buf = serialize_key_blob(key_blob, buf, end);
540    return upgrade_params.Serialize(buf, end);
541}
542
543bool UpgradeKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
544    return deserialize_key_blob(&key_blob, buf_ptr, end) &&
545           upgrade_params.Deserialize(buf_ptr, end);
546}
547
548UpgradeKeyResponse::~UpgradeKeyResponse() {
549    delete[] upgraded_key.key_material;
550}
551
552size_t UpgradeKeyResponse::NonErrorSerializedSize() const {
553    return key_blob_size(upgraded_key);
554}
555
556uint8_t* UpgradeKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
557    return serialize_key_blob(upgraded_key, buf, end);
558}
559
560bool UpgradeKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
561    return deserialize_key_blob(&upgraded_key, buf_ptr, end);
562}
563
564}  // namespace keymaster
565