1 /*
2  * Copyright (C) 2021 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 #define TLOG_TAG "keybox"
18 
19 #include <assert.h>
20 #include <inttypes.h>
21 #include <lk/list.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <uapi/err.h>
26 
27 #include <trusty_log.h>
28 
29 #include "keybox.h"
30 
31 /*
32  * THIS DOES NOT PROVIDE ANY SECURITY
33  *
34  * This is not a useful wrapping system. This is just intended as enough to mock
35  * that:
36  * 1. The wrapped data and unwrapped data are not the same.
37  * 2. The wrapped data will fail to unwrap if it is trivially tampered with.
38  */
keybox_unwrap(const uint8_t * wrapped_keybox,size_t wrapped_keybox_len,uint8_t * keybox_plaintext,size_t keybox_plaintext_buf_len,size_t * keybox_plaintext_len)39 enum keybox_status keybox_unwrap(const uint8_t* wrapped_keybox,
40                                  size_t wrapped_keybox_len,
41                                  uint8_t* keybox_plaintext,
42                                  size_t keybox_plaintext_buf_len,
43                                  size_t* keybox_plaintext_len) {
44     if (wrapped_keybox_len < 1) {
45         TLOGE("Wrapped keybox too short: %zu\n", wrapped_keybox_len);
46         return KEYBOX_STATUS_INVALID_REQUEST;
47     }
48 
49     if (keybox_plaintext_buf_len < wrapped_keybox_len - 1) {
50         TLOGE("Unwrapped keybox buffer too short: %zu\n",
51               keybox_plaintext_buf_len);
52         return KEYBOX_STATUS_INVALID_REQUEST;
53     }
54 
55     /* Validate checksum */
56     uint8_t checksum = 0;
57     for (size_t i = 0; i < wrapped_keybox_len - 1; i++) {
58         checksum ^= wrapped_keybox[i];
59     }
60 
61     if (checksum != wrapped_keybox[wrapped_keybox_len - 1]) {
62         TLOGE("Invalid checksum\n");
63         return KEYBOX_STATUS_UNWRAP_FAIL;
64     }
65 
66     /* Flip bits with masking byte */
67     for (size_t i = 0; i < wrapped_keybox_len - 1; i++) {
68         keybox_plaintext[i] = wrapped_keybox[i] ^ 0x42;
69     }
70 
71     *keybox_plaintext_len = wrapped_keybox_len - 1;
72 
73     return KEYBOX_STATUS_SUCCESS;
74 }
75