3030#include "hmac.h"
3131#include "layout2.h"
3232#include "memzero.h"
33+ #include "protect.h"
3334#if !EMULATOR
3435#include "mi2c.h"
3536#endif
@@ -89,6 +90,11 @@ typedef enum {
8990
9091static U2F_STATE last_req_state = INIT ;
9192
93+ static bool input_pin = false;
94+ static bool first_package = true;
95+ static uint32_t package_len = 0 , rec_len = 0 ;
96+ bool u2f_init_command = false;
97+
9298typedef struct {
9399 uint8_t reserved ;
94100 uint8_t appId [U2F_APPID_SIZE ];
@@ -132,6 +138,7 @@ U2F_ReadBuffer *reader;
132138void u2fhid_read (char tiny , const U2FHID_FRAME * f ) {
133139 // Always handle init packets directly
134140 if (f -> init .cmd == U2FHID_INIT ) {
141+ u2f_init_command = true;
135142 u2fhid_init (f );
136143 if (tiny && reader && f -> cid == cid ) {
137144 // abort current channel
@@ -142,6 +149,24 @@ void u2fhid_read(char tiny, const U2FHID_FRAME *f) {
142149 return ;
143150 }
144151
152+ if (layoutLast == layoutInputPin ) {
153+ if (first_package ) {
154+ first_package = false;
155+ package_len = MSG_LEN (* f );
156+ rec_len = sizeof (f -> cont .data );
157+ while (rec_len < package_len ) {
158+ usbPoll ();
159+ }
160+ send_u2f_error (U2F_SW_CONDITIONS_NOT_SATISFIED );
161+ first_package = true;
162+ return ;
163+ } else {
164+ rec_len += sizeof (f -> cont .data );
165+ return ;
166+ }
167+ return ;
168+ }
169+
145170 if (tiny ) {
146171 // read continue packet
147172 if (reader == 0 || cid != f -> cid ) {
@@ -259,6 +284,10 @@ void u2fhid_read_start(const U2FHID_FRAME *f) {
259284 // standard requires to remember button press for 10 seconds.
260285 dialog_timeout = 10 * U2F_TIMEOUT ;
261286 }
287+ if (reader == 0 ) {
288+ layoutHome ();
289+ return ;
290+ }
262291 }
263292
264293 if (reader -> cmd == 0 ) {
@@ -627,6 +656,20 @@ void u2f_register(const APDU *a) {
627656 return ;
628657 }
629658
659+ if (!session_isUnlocked ()) {
660+ input_pin = true;
661+ send_u2f_error (U2F_SW_CONDITIONS_NOT_SATISFIED );
662+ }
663+
664+ protectPinOnDevice (true, true);
665+
666+ if (input_pin ) {
667+ input_pin = false;
668+ last_req_state = REG ;
669+ dialog_timeout = U2F_TIMEOUT ;
670+ return ;
671+ }
672+
630673 // Validate basic request parameters
631674 debugLog (0 , "" , "u2f register" );
632675 if (APDU_LEN (* a ) != sizeof (U2F_REGISTER_REQ )) {
@@ -770,6 +813,20 @@ void u2f_authenticate(const APDU *a) {
770813 return ;
771814 }
772815
816+ if (!session_isUnlocked ()) {
817+ input_pin = true;
818+ send_u2f_error (U2F_SW_CONDITIONS_NOT_SATISFIED );
819+ }
820+
821+ protectPinOnDevice (true, true);
822+
823+ if (input_pin ) {
824+ input_pin = false;
825+ last_req_state = AUTH ;
826+ dialog_timeout = U2F_TIMEOUT ;
827+ return ;
828+ }
829+
773830 if (a -> p1 == U2F_AUTH_CHECK_ONLY ) {
774831 debugLog (0 , "" , "u2f authenticate check" );
775832 // This is a success for a good keyhandle
0 commit comments