xref: /aosp_15_r20/external/gsc-utils/include/u2f.h (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
1 // Common U2F raw message format header - Review Draft
2 // 2014-10-08
3 // Editor: Jakob Ehrensvard, Yubico, [email protected]
4 
5 #ifndef __U2F_H_INCLUDED__
6 #define __U2F_H_INCLUDED__
7 
8 /**
9  * Note: This header file should be self-sufficient as it is shared
10  * with other boards and with userland daemons (u2fd).
11  *
12  * chromeos-ec-headers package installs it in ChromeOS development environment.
13  *
14  */
15 
16 #ifdef _MSC_VER /* Windows */
17 typedef unsigned char uint8_t;
18 typedef unsigned short uint16_t;
19 typedef unsigned int uint32_t;
20 typedef unsigned long int uint64_t;
21 #else
22 #include <stdint.h>
23 #endif
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /* General constants */
30 
31 #define U2F_EC_KEY_SIZE	      32 /* EC key size in bytes, NIST P-256 Curve */
32 #define U2F_EC_POINT_SIZE     ((U2F_EC_KEY_SIZE * 2) + 1) /* Size of EC point */
33 #define U2F_MAX_KH_SIZE	      128 /* Max size of key handle */
34 #define U2F_MAX_ATT_CERT_SIZE 2048 /* Max size of attestation certificate */
35 #define U2F_MAX_EC_SIG_SIZE   72 /* Max size of DER coded EC signature */
36 #define U2F_CTR_SIZE	      4 /* Size of counter field */
37 #define U2F_APPID_SIZE	      32 /* Size of application id */
38 #define U2F_CHAL_SIZE	      32 /* Size of challenge */
39 #define U2F_MAX_ATTEST_SIZE   256 /* Size of largest blob to sign */
40 #define U2F_P256_SIZE	      32
41 /* Origin seed is a random nonce generated during key handle creation. */
42 #define U2F_ORIGIN_SEED_SIZE 32
43 #define U2F_USER_SECRET_SIZE 32 /* Size of user secret */
44 
45 #define U2F_AUTH_TIME_SECRET_SIZE 32
46 
47 #define SHA256_DIGEST_SIZE	32
48 #define U2F_MESSAGE_DIGEST_SIZE SHA256_DIGEST_SIZE
49 
50 #define CORP_CHAL_SIZE 16
51 #define CORP_SALT_SIZE 65
52 
53 #define ENC_SIZE(x) ((x + 7) & 0xfff8)
54 
55 /* EC (uncompressed) point */
56 
57 #define U2F_POINT_UNCOMPRESSED 0x04 /* Uncompressed point format */
58 
59 struct u2f_ec_point {
60 	uint8_t pointFormat; /* Point type */
61 	uint8_t x[U2F_EC_KEY_SIZE]; /* X-value */
62 	uint8_t y[U2F_EC_KEY_SIZE]; /* Y-value */
63 };
64 
65 /* Request Flags. */
66 
67 #define U2F_AUTH_ENFORCE    0x03 /* Enforce user presence and sign */
68 #define U2F_AUTH_CHECK_ONLY 0x07 /* Check only */
69 #define U2F_AUTH_FLAG_TUP   0x01 /* Test of user presence set */
70 /* The key handle can be used with fingerprint or PIN. */
71 #define U2F_UV_ENABLED_KH 0x08
72 
73 /* Request v2 key handle. Should be used with U2F_UV_ENABLED_KH */
74 #define U2F_V2_KH      0x10
75 #define U2F_V2_KH_MASK (U2F_V2_KH | U2F_UV_ENABLED_KH)
76 
77 #define U2F_KH_VERSION_1 0x01
78 #define U2F_KH_VERSION_2 0x02
79 
80 #define U2F_AUTHORIZATION_SALT_SIZE 16
81 #define U2F_V0_KH_SIZE		    64
82 
83 /**
84  * Key handle version = 1 for WebAuthn, bound to device and user.
85  */
86 #define U2F_V1_KH_SIZE 113
87 
88 /* Header is composed of version || origin_seed || kh_hmac */
89 #define U2F_V1_KH_HEADER_SIZE (U2F_ORIGIN_SEED_SIZE + SHA256_DIGEST_SIZE + 1)
90 
91 /**
92  * Key handle version = 2 for WebAuthn, bound to device and user.
93  */
94 #define U2F_V2_KH_SIZE 81
95 
96 /* Header is composed of version || origin_seed */
97 #define U2F_V2_KH_HEADER_SIZE (U2F_ORIGIN_SEED_SIZE + 1)
98 
99 struct u2f_signature {
100 	uint8_t sig_r[U2F_EC_KEY_SIZE]; /* Signature */
101 	uint8_t sig_s[U2F_EC_KEY_SIZE]; /* Signature */
102 };
103 
104 struct u2f_key_handle {
105 	uint8_t origin_seed[U2F_ORIGIN_SEED_SIZE];
106 	uint8_t hmac[SHA256_DIGEST_SIZE];
107 };
108 
109 struct u2f_versioned_key_handle_header {
110 	uint8_t version;
111 	uint8_t origin_seed[U2F_ORIGIN_SEED_SIZE];
112 	uint8_t kh_hmac[SHA256_DIGEST_SIZE];
113 };
114 
115 struct u2f_versioned_key_handle {
116 	struct u2f_versioned_key_handle_header header;
117 	/* Optionally checked in u2f_sign. */
118 	uint8_t authorization_salt[U2F_AUTHORIZATION_SALT_SIZE];
119 	uint8_t authorization_hmac[SHA256_DIGEST_SIZE];
120 };
121 
122 /**
123  * Alternative definitions of key handles.
124  *
125  *  struct u2f_key_handle_v0 == struct u2f_key_handle
126  *  struct u2f_key_handle_v1 == struct u2f_versioned_key_handle
127  *
128  */
129 
130 /* Key handle version = 0, only bound to device. */
131 struct u2f_key_handle_v0 {
132 	uint8_t origin_seed[U2F_ORIGIN_SEED_SIZE];
133 	uint8_t hmac[SHA256_DIGEST_SIZE];
134 };
135 
136 /* Key handle version = 1, bound to device and user. */
137 struct u2f_key_handle_v1 {
138 	uint8_t version;
139 	uint8_t origin_seed[U2F_ORIGIN_SEED_SIZE];
140 	/* HMAC(u2f_hmac_key, origin || user || origin seed || version) */
141 	uint8_t kh_hmac[SHA256_DIGEST_SIZE];
142 	/* Optionally checked in u2f_sign. */
143 	uint8_t authorization_salt[U2F_AUTHORIZATION_SALT_SIZE];
144 	/**
145 	 * HMAC(u2f_hmac_key,
146 	 *      auth_salt || version || origin_seed
147 	 *      || kh_hmac || authTimeSecretHash)
148 	 */
149 	uint8_t authorization_hmac[SHA256_DIGEST_SIZE];
150 };
151 
152 /* Key handle version = 2, bound to device and user. */
153 struct u2f_key_handle_v2 {
154 	uint8_t version;
155 	uint8_t origin_seed[U2F_ORIGIN_SEED_SIZE];
156 	/* Always checked in u2f_sign. */
157 	uint8_t authorization_salt[U2F_AUTHORIZATION_SALT_SIZE];
158 	/**
159 	 * HMAC(u2f_hmac_key,
160 	 *      auth_salt || version || origin_seed || origin ||
161 	 *      user || authTimeSecretHash)
162 	 */
163 	uint8_t authorization_hmac[SHA256_DIGEST_SIZE];
164 };
165 
166 union u2f_key_handle_variant {
167 	struct u2f_key_handle_v0 v0;
168 	struct u2f_key_handle_v1 v1;
169 	struct u2f_key_handle_v2 v2;
170 };
171 
172 /* TODO(louiscollard): Add Descriptions. */
173 
174 struct u2f_generate_req {
175 	uint8_t appId[U2F_APPID_SIZE]; /* Application id */
176 	uint8_t userSecret[U2F_USER_SECRET_SIZE];
177 	uint8_t flags;
178 	/*
179 	 * If generating versioned KH, derive an hmac from it and append to
180 	 * the key handle. Otherwise unused.
181 	 */
182 	uint8_t authTimeSecretHash[SHA256_DIGEST_SIZE];
183 };
184 
185 struct u2f_generate_resp {
186 	struct u2f_ec_point pubKey; /* Generated public key */
187 	struct u2f_key_handle keyHandle;
188 };
189 
190 struct u2f_generate_versioned_resp {
191 	struct u2f_ec_point pubKey; /* Generated public key */
192 	struct u2f_versioned_key_handle keyHandle;
193 };
194 
195 struct u2f_generate_versioned_resp_v2 {
196 	struct u2f_ec_point pubKey; /* Generated public key */
197 	struct u2f_key_handle_v2 keyHandle;
198 };
199 
200 /**
201  * Combined type for U2F_GENERATE response. Length of response size
202  * should be used to determine which version of key handle is generated.
203  * Caller may check that response matches request flags.
204  */
205 union u2f_generate_response {
206 	struct u2f_generate_resp v0;
207 	struct u2f_generate_versioned_resp v1;
208 	struct u2f_generate_versioned_resp_v2 v2;
209 };
210 
211 struct u2f_sign_req {
212 	uint8_t appId[U2F_APPID_SIZE]; /* Application id */
213 	uint8_t userSecret[U2F_USER_SECRET_SIZE];
214 	struct u2f_key_handle keyHandle;
215 	uint8_t hash[U2F_P256_SIZE];
216 	uint8_t flags;
217 };
218 
219 struct u2f_sign_versioned_req {
220 	uint8_t appId[U2F_APPID_SIZE]; /* Application id */
221 	uint8_t userSecret[U2F_USER_SECRET_SIZE];
222 	uint8_t authTimeSecret[U2F_AUTH_TIME_SECRET_SIZE];
223 	uint8_t hash[U2F_P256_SIZE];
224 	uint8_t flags;
225 	struct u2f_versioned_key_handle keyHandle;
226 };
227 
228 struct u2f_sign_versioned_req_v2 {
229 	uint8_t appId[U2F_APPID_SIZE]; /* Application id */
230 	uint8_t userSecret[U2F_USER_SECRET_SIZE];
231 	uint8_t authTimeSecret[U2F_AUTH_TIME_SECRET_SIZE];
232 	uint8_t hash[U2F_P256_SIZE];
233 	uint8_t flags;
234 	struct u2f_key_handle_v2 keyHandle;
235 };
236 
237 /**
238  * Combined type for U2F_SIGN request. Length of request size
239  * is used to determine which version of key handle is provided.
240  */
241 union u2f_sign_request {
242 	struct u2f_sign_req v0;
243 	struct u2f_sign_versioned_req v1;
244 	struct u2f_sign_versioned_req_v2 v2;
245 };
246 
247 struct u2f_sign_resp {
248 	uint8_t sig_r[U2F_P256_SIZE]; /* Signature */
249 	uint8_t sig_s[U2F_P256_SIZE]; /* Signature */
250 };
251 
252 struct u2f_attest_req {
253 	uint8_t userSecret[U2F_USER_SECRET_SIZE];
254 	uint8_t format;
255 	uint8_t dataLen;
256 	/* struct g2f_register_msg_vX or corp_register_msg_vX */
257 	uint8_t data[U2F_MAX_ATTEST_SIZE];
258 };
259 
260 struct g2f_register_msg_v0 {
261 	uint8_t reserved;
262 	uint8_t app_id[U2F_APPID_SIZE];
263 	uint8_t challenge[U2F_CHAL_SIZE];
264 	struct u2f_key_handle_v0 key_handle;
265 	struct u2f_ec_point public_key;
266 };
267 
268 struct corp_attest_data {
269 	uint8_t challenge[CORP_CHAL_SIZE];
270 	struct u2f_ec_point public_key;
271 	uint8_t salt[CORP_SALT_SIZE];
272 };
273 
274 struct corp_register_msg_v0 {
275 	struct corp_attest_data data;
276 	uint8_t app_id[U2F_APPID_SIZE];
277 	struct u2f_key_handle_v0 key_handle;
278 };
279 
280 union u2f_attest_msg_variant {
281 	struct g2f_register_msg_v0 g2f;
282 	struct corp_register_msg_v0 corp;
283 };
284 
285 struct u2f_attest_resp {
286 	uint8_t sig_r[U2F_P256_SIZE];
287 	uint8_t sig_s[U2F_P256_SIZE];
288 };
289 
290 /* Command status responses */
291 
292 #define U2F_SW_NO_ERROR	  0x9000 /* SW_NO_ERROR */
293 #define U2F_SW_WRONG_DATA 0x6A80 /* SW_WRONG_DATA */
294 #define U2F_SW_CONDITIONS_NOT_SATISFIED       \
295 	0x6985 /* SW_CONDITIONS_NOT_SATISFIED \
296 		*/
297 #define U2F_SW_COMMAND_NOT_ALLOWED 0x6986 /* SW_COMMAND_NOT_ALLOWED */
298 #define U2F_SW_INS_NOT_SUPPORTED   0x6D00 /* SW_INS_NOT_SUPPORTED */
299 
300 /* Protocol extensions */
301 
302 /* Non-standardized command status responses */
303 #define U2F_SW_CLA_NOT_SUPPORTED 0x6E00
304 #define U2F_SW_WRONG_LENGTH	 0x6700
305 #define U2F_SW_WTF		 0x6f00
306 
307 /* Additional flags for P1 field */
308 #define G2F_ATTEST  0x80 /* Fixed attestation key */
309 #define G2F_CONSUME 0x02 /* Consume presence */
310 
311 /*
312  * The key handle format was changed when support for user secrets was added.
313  * U2F_SIGN requests that specify this flag will first try to validate the key
314  * handle as a new format key handle, and if that fails, will fall back to
315  * treating it as a legacy key handle (without user secrets).
316  */
317 #define SIGN_LEGACY_KH 0x40
318 
319 /* U2F Attest format for U2F Register Response. */
320 #define U2F_ATTEST_FORMAT_REG_RESP 0
321 
322 /* Corp Attest format for U2F Register Response. */
323 #define CORP_ATTEST_FORMAT_REG_RESP 1
324 
325 /* Vendor command to enable/disable the extensions */
326 #define U2F_VENDOR_MODE U2F_VENDOR_LAST
327 
328 #ifdef __cplusplus
329 }
330 #endif
331 
332 #endif /* __U2F_H_INCLUDED__ */
333