1 /*
2  * Copyright (C) 2016 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 #ifndef _NANOHUB_NANOHUB_H_
18 #define _NANOHUB_NANOHUB_H_
19 
20 #include <inttypes.h>
21 #include <nanohub/aes.h>
22 
23 /* this file is collection of nanohub-related definitions shared between multiple parties,
24  * including but not limited to: HAL, Kernel, utilities, nanohub FW
25  * it provides minimum details on nanohub implementation, necessary to reliably identify it, and
26  * generate/parse compatible images
27  */
28 
29 #define NANOAPP_SIGNED_FLAG    0x1  // contents is signed with one or more signature block(s)
30 #define NANOAPP_ENCRYPTED_FLAG 0x2  // contents is encrypted with exactly one encryption key
31 
32 #define NANOAPP_AOSP_MAGIC (((uint32_t)'N' <<  0) | ((uint32_t)'A' <<  8) | ((uint32_t)'N' << 16) | ((uint32_t)'O' << 24))
33 #define NANOAPP_FW_MAGIC (((uint32_t)'N' <<  0) | ((uint32_t)'B' <<  8) | ((uint32_t)'I' << 16) | ((uint32_t)'N' << 24))
34 #define GOOGLE_LAYOUT_MAGIC (((uint32_t)'G' <<  0) | ((uint32_t)'o' <<  8) | ((uint32_t)'o' << 16) | ((uint32_t)'g' << 24))
35 
36 // The binary format below is in little endian format
37 struct nano_app_binary_t {
38     uint32_t header_version;       // 0x1 for this version
39     uint32_t magic;                // "NANO"
40     uint64_t app_id;               // App Id contains vendor id
41     uint32_t app_version;          // Version of the app
42     uint32_t flags;                // Signed, encrypted
43     uint64_t hw_hub_type;          // which hub type is this compiled for
44     uint32_t reserved[2];          // Should be all zeroes
45     uint8_t  custom_binary[0];     // start of custom binary data
46 };
47 
48 // we translate AOSP header into FW header: this header is in LE format
49 // please maintain natural alignment for every field (matters to Intel; otherwise is has to be declared as packed)
50 struct FwCommonHdr {
51     uint32_t magic;         // external & internal: NANOAPP_FW_MAGIC
52     uint16_t fwVer;         // external & internal: set to 1; header version
53     uint16_t fwFlags;       // external & internal: class : EXTERNAL/INTERNAL, EXEC/NOEXEC, APP/KERNEL/EEDATA/...
54     uint64_t appId;         // external: copy from AOSP header; internal: defined locally
55     uint32_t appVer;        // external: copy from AOSP header; internal: defined locally
56     uint8_t  payInfoType;   // external: copy ImageLayout::payload; internal: LAYOUT_APP
57     uint8_t  payInfoSize;   // sizeof(PayloadInfo) for this payload type
58     uint8_t  rfu[2];        // filled with 0xFF
59 };
60 
61 struct SectInfo {
62     uint32_t data_start;
63     uint32_t data_end;
64     uint32_t data_data;
65 
66     uint32_t bss_start;
67     uint32_t bss_end;
68 
69     uint32_t got_start;
70     uint32_t got_end;
71     uint32_t rel_start;
72     uint32_t rel_end;
73 };
74 
75 // this is platform-invariant version of struct TaskFuncs (from seos.h)
76 struct AppVectors {
77     uint32_t init;
78     uint32_t end;
79     uint32_t handle;
80 };
81 
82 #define FLASH_RELOC_OFFSET offsetof(struct AppHdr, sect)        // used by appSupport.c at run time
83 #define BINARY_RELOC_OFFSET offsetof(struct BinHdr, sect)       // used by postprocess at build time
84 
85 struct BinCommonHdr {
86     uint32_t magic;
87     uint32_t appVer;
88 };
89 
90 // binary nanoapp image (.bin) produced by objcopy starts with this binary header (LE)
91 struct BinHdr {
92     struct BinCommonHdr hdr;
93     struct SectInfo     sect;
94     struct AppVectors   vec;
95 };
96 
97 // FW nanoapp image starts with this binary header (LE) in flash
98 struct AppHdr {
99     struct FwCommonHdr hdr;
100     struct SectInfo    sect;
101     struct AppVectors  vec;
102 };
103 
104 struct AppSecSignHdr {
105     uint32_t appDataLen;
106 };
107 
108 struct AppSecEncrHdr {
109     uint64_t keyID;
110     uint32_t dataLen;
111     uint32_t IV[AES_BLOCK_WORDS];
112 };
113 
114 #define LAYOUT_APP  1
115 #define LAYOUT_KEY  2
116 #define LAYOUT_OS   3
117 #define LAYOUT_DATA 4
118 
119 struct ImageLayout {
120     uint32_t magic;     // Layout ID: (GOOGLE_LAYOUT_MAGIC for this implementation)
121     uint8_t  version;   // layout version
122     uint8_t  payload;   // type of payload: APP, SECRET KEY, OS IMAGE, USER DATA, ...
123     uint16_t flags;     // layout flags: extra options for certain payload types; payload-specific
124 };
125 
126 // .napp image starts with this binary header (LE)
127 // it is optionally followed by AppSecSignHdr and/or AppSecEncrHdr
128 // all of the above are included in signing hash, but never encrypted
129 // encryption (if enabled) starts immediately after those
130 struct ImageHeader {
131     struct nano_app_binary_t aosp;
132     struct ImageLayout   layout;
133 };
134 
135 #define CKK_RSA 0x00
136 #define CKK_AES 0x1F
137 
138 #define CKO_PUBLIC_KEY  0x02
139 #define CKO_PRIVATE_KEY 0x03
140 #define CKO_SECRET_KEY  0x04
141 
142 // flags
143 #define FL_KI_ENFORCE_ID 0x0001  // if set, size, key_type, obj_type must be valid
144 
145 // payload header format: LAYOUT_KEY
146 struct KeyInfo {
147     union {
148         struct {
149             uint16_t id;        // arbitrary number, != 0, equivalent of PKCS#11 name
150             uint16_t flags;     // key flags (additional PKCS#11 attrs, unused for now; must be 0)
151             uint16_t size;      // key size in bits
152             uint8_t  key_type;  // 8 LSB of PKCS-11 CKK_<KEY TYPE>
153             uint8_t  obj_type;  // 8 LSB of PKCS-11 CKO_<OBJ TYPE>
154         };
155         uint64_t data;          // complete 64-bit key-id, unique within this APP namespace (complete id is <APP_ID | KEY_INFO> 128 bits)
156     };
157 };
158 
159 #define AES_KEY_ID(_id) (((struct KeyInfo){ .key_type = CKK_AES, .obj_type = CKO_SECRET_KEY, .size = 256, .id = (_id) }).data)
160 
161 // payload header format: LAYOUT_APP
162 struct AppInfo {
163     struct SectInfo   sect;
164     struct AppVectors vec;
165 };
166 
167 #define OS_UPDT_MARKER_INPROGRESS     0xFF
168 #define OS_UPDT_MARKER_DOWNLOADED     0xFE
169 #define OS_UPDT_MARKER_VERIFIED       0xF0
170 #define OS_UPDT_MARKER_INVALID        0x00
171 #define OS_UPDT_MAGIC                 "Nanohub OS" //11 bytes incl terminator
172 
173 // payload header format: LAYOUT_OS
174 struct OsUpdateHdr {
175     char magic[11];
176     uint8_t marker; //OS_UPDT_MARKER_INPROGRESS -> OS_UPDT_MARKER_DOWNLOADED -> OS_UPDT_MARKER_VERIFIED / OS_UPDT_INVALID
177     uint32_t size;  //does not include the mandatory signature (using device key) that follows
178 };
179 
180 // payload header format: LAYOUT_DATA
181 struct DataInfo {
182     uint32_t id;
183     uint32_t size;
184 };
185 
186 #endif // _NANOHUB_NANOHUB_H_
187