summaryrefslogtreecommitdiff
path: root/include/u2f.h
blob: 1a445f8f4aec2cf6601b130b7c702c2b34b5a97c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Common U2F raw message format header - Review Draft
// 2014-10-08
// Editor: Jakob Ehrensvard, Yubico, jakob@yubico.com

#ifndef __U2F_H_INCLUDED__
#define __U2F_H_INCLUDED__

#ifdef _MSC_VER  // Windows
typedef unsigned char     uint8_t;
typedef unsigned short    uint16_t;
typedef unsigned int      uint32_t;
typedef unsigned long int uint64_t;
#else
#include <stdint.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

// General constants

#define U2F_EC_KEY_SIZE         32      // EC key size in bytes
#define U2F_EC_POINT_SIZE       ((U2F_EC_KEY_SIZE * 2) + 1) // Size of EC point
#define U2F_MAX_KH_SIZE         128     // Max size of key handle
#define U2F_MAX_ATT_CERT_SIZE   2048    // Max size of attestation certificate
#define U2F_MAX_EC_SIG_SIZE     72      // Max size of DER coded EC signature
#define U2F_CTR_SIZE            4       // Size of counter field
#define U2F_APPID_SIZE          32      // Size of application id
#define U2F_CHAL_SIZE           32      // Size of challenge
#define U2F_MAX_ATTEST_SIZE     256     // Size of largest blob to sign
#define U2F_P256_SIZE           32
#define U2F_FIXED_KH_SIZE       64      // Size of fixed size key handles

#define ENC_SIZE(x)             ((x + 7) & 0xfff8)

// EC (uncompressed) point

#define U2F_POINT_UNCOMPRESSED  0x04    // Uncompressed point format

typedef struct {
    uint8_t pointFormat;                // Point type
    uint8_t x[U2F_EC_KEY_SIZE];         // X-value
    uint8_t y[U2F_EC_KEY_SIZE];         // Y-value
} U2F_EC_POINT;

// U2F native commands

#define U2F_REGISTER            0x01    // Registration command
#define U2F_AUTHENTICATE        0x02    // Authenticate/sign command
#define U2F_VERSION             0x03    // Read version string command

#define U2F_VENDOR_FIRST        0x40    // First vendor defined command
#define U2F_VENDOR_LAST         0xbf    // Last vendor defined command

// U2F_CMD_REGISTER command defines

#define U2F_REGISTER_ID         0x05    // Version 2 registration identifier
#define U2F_REGISTER_HASH_ID    0x00    // Version 2 hash identintifier

typedef struct {
    uint8_t chal[U2F_CHAL_SIZE];        // Challenge
    uint8_t appId[U2F_APPID_SIZE];      // Application id
} U2F_REGISTER_REQ;

typedef struct {
    uint8_t registerId;                 // Registration identifier (U2F_REGISTER_ID_V2)
    U2F_EC_POINT pubKey;                // Generated public key
    uint8_t keyHandleLen;               // Length of key handle
    uint8_t keyHandleCertSig[
        U2F_MAX_KH_SIZE +               // Key handle
        U2F_MAX_ATT_CERT_SIZE +         // Attestation certificate
        U2F_MAX_EC_SIG_SIZE];           // Registration signature
} U2F_REGISTER_RESP;

// U2F_CMD_AUTHENTICATE command defines

// Authentication control byte

#define U2F_AUTH_ENFORCE        0x03    // Enforce user presence and sign
#define U2F_AUTH_CHECK_ONLY     0x07    // Check only
#define U2F_AUTH_FLAG_TUP       0x01    // Test of user presence set

typedef struct {
    uint8_t chal[U2F_CHAL_SIZE];        // Challenge
    uint8_t appId[U2F_APPID_SIZE];      // Application id
    uint8_t keyHandleLen;               // Length of key handle
    uint8_t keyHandle[U2F_MAX_KH_SIZE]; // Key handle
} U2F_AUTHENTICATE_REQ;

typedef struct {
    uint8_t flags;                      // U2F_AUTH_FLAG_ values
    uint8_t ctr[U2F_CTR_SIZE];          // Counter field (big-endian)
    uint8_t sig[U2F_MAX_EC_SIG_SIZE];   // Signature
} U2F_AUTHENTICATE_RESP;

// TODO(louiscollard): Add Descriptions.

typedef struct {
    uint8_t appId[U2F_APPID_SIZE];      // Application id
    uint8_t userSecret[U2F_P256_SIZE];
    uint8_t flags;
} U2F_GENERATE_REQ;

typedef struct {
    U2F_EC_POINT pubKey;                   // Generated public key
    uint8_t keyHandle[U2F_FIXED_KH_SIZE];  // Key handle
} U2F_GENERATE_RESP;

typedef struct {
    uint8_t appId[U2F_APPID_SIZE];         // Application id
    uint8_t userSecret[U2F_P256_SIZE];
    uint8_t keyHandle[U2F_FIXED_KH_SIZE];  // Key handle
    uint8_t hash[U2F_P256_SIZE];
    uint8_t flags;
} U2F_SIGN_REQ;

typedef struct {
    uint8_t sig_r[U2F_P256_SIZE];   // Signature
    uint8_t sig_s[U2F_P256_SIZE];   // Signature
} U2F_SIGN_RESP;

typedef struct {
    uint8_t userSecret[U2F_P256_SIZE];
    uint8_t format;
    uint8_t dataLen;
    uint8_t data[U2F_MAX_ATTEST_SIZE];
} U2F_ATTEST_REQ;

typedef struct {
    uint8_t sig_r[U2F_P256_SIZE];
    uint8_t sig_s[U2F_P256_SIZE];
} U2F_ATTEST_RESP;

// Command status responses

#define U2F_SW_NO_ERROR                 0x9000 // SW_NO_ERROR
#define U2F_SW_WRONG_DATA               0x6A80 // SW_WRONG_DATA
#define U2F_SW_CONDITIONS_NOT_SATISFIED 0x6985 // SW_CONDITIONS_NOT_SATISFIED
#define U2F_SW_COMMAND_NOT_ALLOWED      0x6986 // SW_COMMAND_NOT_ALLOWED
#define U2F_SW_INS_NOT_SUPPORTED        0x6D00 // SW_INS_NOT_SUPPORTED

// Protocol extensions

// Non-standardized command status responses
#define U2F_SW_CLA_NOT_SUPPORTED        0x6E00
#define U2F_SW_WRONG_LENGTH             0x6700
#define U2F_SW_WTF                      0x6f00

// Additional flags for P1 field
#define G2F_ATTEST      0x80    // Fixed attestation key
#define G2F_CONSUME     0x02    // Consume presence

// The key handle format was changed when support for user secrets was added.
// U2F_SIGN requests that specify this flag will first try to validate the
// key handle as a new format key handle, and if that fails, will fall back
// to treating it as a legacy key handle (without user secrets).
#define SIGN_LEGACY_KH  0x40

// U2F Attest format for U2F Register Response.
#define U2F_ATTEST_FORMAT_REG_RESP      0

// Vendor command to enable/disable the extensions
#define U2F_VENDOR_MODE U2F_VENDOR_LAST

#ifdef __cplusplus
}
#endif

#endif  // __U2F_H_INCLUDED__