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