** **
** Y K D E F - Common Yubikey project header **
** **
-** Date / Rev / Sign / Remark **
-** 06-06-03 / 0.9.0 / J E / Main **
-** 06-08-25 / 1.0.0 / J E / Rewritten for final spec **
-** 08-06-03 / 1.3.0 / J E / Added static OTP feature **
-** 09-06-02 / 2.0.0 / J E / Added version 2 flags **
+** Date / Rev / Sign / Remark **
+** 06-06-03 / 0.9.0 / J E / Main **
+** 06-08-25 / 1.0.0 / J E / Rewritten for final spec **
+** 08-06-03 / 1.3.0 / J E / Added static OTP feature **
+** 09-06-02 / 2.0.0 / J E / Added version 2 flags **
+** 09-09-23 / 2.1.0 / J E / Added version 2.1 flags (OATH-HOTP) **
** **
*****************************************************************************************/
#define FIXED_SIZE 16 /* Max size of fixed field */
#define KEY_SIZE 16 /* Size of AES key */
+#define KEY_SIZE_OATH 20 /* Size of OATH-HOTP key (key field + first 4 of UID field) */
#define ACC_CODE_SIZE 6 /* Size of access code to re-program device */
struct config_st {
/* Ticket flags **************************************************************/
-/* Yubikey 1 and newer */
+/* Yubikey 1 and above */
#define TKTFLAG_TAB_FIRST 0x01 /* Send TAB before first part */
#define TKTFLAG_APPEND_TAB1 0x02 /* Send TAB after first part */
#define TKTFLAG_APPEND_TAB2 0x04 /* Send TAB after second part */
#define TKTFLAG_APPEND_DELAY2 0x10 /* Add 0.5s delay after second part */
#define TKTFLAG_APPEND_CR 0x20 /* Append CR as final character */
-/* Yubikey 2 only */
+/* Yubikey 2 and above */
#define TKTFLAG_PROTECT_CFG2 0x80 /* Block update of config 2 unless config 2 is configured and has this bit set */
+/* Yubikey 2.1 and above */
+#define TKTFLAG_OATH_HOTP 0x40 /* OATH HOTP mode */
+
/* Configuration flags *******************************************************/
-/* Yubikey 1 and newer */
+/* Yubikey 1 and above */
#define CFGFLAG_SEND_REF 0x01 /* Send reference string (0..F) before data */
#define CFGFLAG_PACING_10MS 0x04 /* Add 10ms intra-key pacing */
#define CFGFLAG_PACING_20MS 0x08 /* Add 20ms intra-key pacing */
#define CFGFLAG_TICKET_FIRST 0x02 /* Send ticket first (default is fixed part) */
#define CFGFLAG_ALLOW_HIDTRIG 0x10 /* Allow trigger through HID/keyboard */
-/* Yubikey 2 only */
+/* Yubikey 2 and above */
#define CFGFLAG_SHORT_TICKET 0x02 /* Send truncated ticket (half length) */
#define CFGFLAG_STRONG_PW1 0x10 /* Strong password policy flag #1 (mixed case) */
#define CFGFLAG_STRONG_PW2 0x40 /* Strong password policy flag #2 (subtitute 0..7 to digits) */
#define CFGFLAG_MAN_UPDATE 0x80 /* Allow manual (local) update of static OTP */
+/* Yubikey 2.1 and above */
+#define CFGFLAG_OATH_HOTP8 0x02 /* Generate 8 digits HOTP rather than 6 digits */
+#define CFGFLAG_OATH_FIXED_MODHEX1 0x10 /* First byte in fixed part sent as modhex */
+#define CFGFLAG_OATH_FIXED_MODHEX2 0x40 /* First two bytes in fixed part sent as modhex */
+#define CFGFLAG_OATH_FIXED_MODHEX 0x50 /* Fixed part sent as modhex */
+#define CFGFLAG_OATH_FIXED_MASK 0x50 /* Mask to get out fixed flags */
+
/* Navigation */
/* NOTE: Navigation isn't available since Yubikey 1.3.5 and is strongly
return cfg->yk_major_version > 1;
}
+static bool vcheck_v21_or_greater(const YKP_CONFIG *cfg)
+{
+ return (cfg->yk_major_version == 2 &&
+ cfg->yk_minor_version >= 1) ||
+ cfg->yk_major_version > 2;
+}
+
#define def_set_charfield(fnname,fieldname,size,extra,vcheck) \
int ykp_set_ ## fnname(YKP_CONFIG *cfg, unsigned char *input, size_t len) \
{ \
def_set_tktflag(APPEND_DELAY2,vcheck_all)
def_set_tktflag(APPEND_CR,vcheck_all)
def_set_tktflag(PROTECT_CFG2,vcheck_no_v1)
+def_set_tktflag(OATH_HOTP,vcheck_v21_or_greater)
def_set_cfgflag(SEND_REF,vcheck_all)
def_set_cfgflag(TICKET_FIRST,vcheck_v1)
def_set_cfgflag(STRONG_PW1,vcheck_no_v1)
def_set_cfgflag(STRONG_PW2,vcheck_no_v1)
def_set_cfgflag(MAN_UPDATE,vcheck_no_v1)
-
+def_set_cfgflag(OATH_HOTP8,vcheck_v21_or_greater)
+def_set_cfgflag(OATH_FIXED_MODHEX1,vcheck_v21_or_greater)
+def_set_cfgflag(OATH_FIXED_MODHEX2,vcheck_v21_or_greater)
+def_set_cfgflag(OATH_FIXED_MODHEX,vcheck_v21_or_greater)
const char str_key_value_separator[] = ": ";
const char str_hex_prefix[] = "h:";
{ TKTFLAG_APPEND_DELAY2, "APPEND_DELAY2", vcheck_all },
{ TKTFLAG_APPEND_CR, "APPEND_CR", vcheck_all },
{ TKTFLAG_PROTECT_CFG2, "PROTECT_CFG2", vcheck_no_v1 },
+ { TKTFLAG_OATH_HOTP, "PROTECT_OATH_HOTP", vcheck_v21_or_greater },
{ 0, "" }
};
{ CFGFLAG_STRONG_PW1, "STRONG_PW1", vcheck_no_v1 },
{ CFGFLAG_STRONG_PW2, "STRONG_PW2", vcheck_no_v1 },
{ CFGFLAG_MAN_UPDATE, "MAN_UPDATE", vcheck_no_v1 },
+ { CFGFLAG_OATH_HOTP8, "OATH_HOTP8", vcheck_v21_or_greater },
+ { CFGFLAG_OATH_FIXED_MODHEX1, "OATH_FIXED_MODHEX1", vcheck_v21_or_greater },
+ { CFGFLAG_OATH_FIXED_MODHEX2, "OATH_FIXED_MODHEX2", vcheck_v21_or_greater },
+ { CFGFLAG_OATH_FIXED_MODHEX, "OATH_FIXED_MODHEX", vcheck_v21_or_greater },
{ 0, "" }
};
/* -*- mode:C; c-file-style: "bsd" -*- */
/*
* Copyright (c) 2008, 2009, Yubico AB
+ * Copyright (c) 2010 Tollef Fog Heen <tfheen@err.no>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
" MUST be 12 characters long.\n"
" access=xxxxxxxxxxx New access code to set, in HEX.\n"
" MUST be 12 characters long.\n"
-" [-]tab-first set/clear the TAB_FIRST ticket flag.\n"
-" [-]append-tab1 set/clear the APPEND_TAB1 ticket flag.\n"
-" [-]append-tab2 set/clear the APPEND_TAB2 ticket flag.\n"
-" [-]append-delay1 set/clear the APPEND_DELAY1 ticket flag.\n"
-" [-]append-delay2 set/clear the APPEND_DELAY2 ticket flag.\n"
-" [-]append-cr set/clear the APPEND_CR ticket flag.\n"
-" [-]protect-cfg2 set/clear the PROTECT_CFG2 ticket flag.\n"
-" (only with Yubikey II!)\n"
-" [-]send-ref set/clear the SEND_REF configuration flag.\n"
-" [-]ticket-first set/clear the TICKET_FIRST configuration flag.\n"
-" (only with Yubikey I!)\n"
-" [-]pacing-10ms set/clear the PACING_10MS configuration flag.\n"
-" [-]pacing-20ms set/clear the PACING_20MS configuration flag.\n"
-" [-]allow-hidtrig set/clear the ALLOW_HIDTRIG configuration flag.\n"
-" (only with Yubikey I!)\n"
-" [-]static-ticket set/clear the STATIC_TICKET configuration flag.\n"
-" [-]short-ticket set/clear the SHORT_TICKET configuration flag.\n"
-" (only with Yubikey II!)\n"
-" [-]strong-pw1 set/clear the STRONG_PW1 configuration flag.\n"
-" (only with Yubikey II!)\n"
-" [-]strong-pw2 set/clear the STRONG_PW2 configuration flag.\n"
-" (only with Yubikey II!)\n"
-" [-]man-update set/clear the MAN_UPDATE configuration flag.\n"
-" (only with Yubikey II!)\n"
+"\n"
+" Ticket flags for all firmware versions:\n"
+" [-]tab-first set/clear TAB_FIRST\n"
+" [-]append-tab1 set/clear APPEND_TAB1\n"
+" [-]append-tab2 set/clear APPEND_TAB2\n"
+" [-]append-delay1 set/clear APPEND_DELAY1\n"
+" [-]append-delay2 set/clear APPEND_DELAY2\n"
+" [-]append-cr set/clear APPEND_CR\n"
+"\n"
+" Ticket flags for firmware version 2.0 and above:\n"
+" [-]protect-cfg2 set/clear PROTECT_CFG2\n"
+"\n"
+" Ticket flags for firmware version 2.1 and above:\n"
+" [-]oath-hotp set/clear OATH_HOTP\n"
+"\n"
+" Configuration flags for all firmware versions:\n"
+" [-]send-ref set/clear SEND_REF\n"
+" [-]pacing-10ms set/clear PACING_10MS\n"
+" [-]pacing-20ms set/clear PACING_20MS\n"
+" [-]static-ticket set/clear STATIC_TICKET\n"
+"\n"
+" Configuration flags for firmware version 1.x only:\n"
+" [-]ticket-first set/clear TICKET_FIRST\n"
+" [-]allow-hidtrig set/clear ALLOW_HIDTRIG\n"
+"\n"
+" Configuration flags for firmware version 2.0 and above:\n"
+" [-]short-ticket set/clear SHORT_TICKET\n"
+" [-]strong-pw1 set/clear STRONG_PW1\n"
+" [-]strong-pw2 set/clear STRONG_PW2\n"
+" [-]man-update set/clear MAN_UPDATE\n"
+"\n"
+" Configuration flags for firmware version 2.1 and above:\n"
+" [-]oath-hotp8 set/clear OATH_HOTP8\n"
+" [-]oath-fixed-modhex1 set/clear OATH_FIXED_MODHEX1\n"
+" [-]oath-fixed-modhex2 set/clear OATH_FIXED_MODHEX2\n"
+" [-]oath-fixed-modhex set/clear OATH_MODHEX\n"
+"\n"
"-y always commit (do not prompt)\n"
"\n"
"-v verbose\n"
ykp_set_access_code(cfg, accbin, accbinlen);
new_access_code = true;
}
- else if (strcmp(optarg, "tab-first") == 0)
- ykp_set_tktflag_TAB_FIRST(cfg, true);
- else if (strcmp(optarg, "-tab-first") == 0)
- ykp_set_tktflag_TAB_FIRST(cfg, false);
- else if (strcmp(optarg, "append-tab1") == 0)
- ykp_set_tktflag_APPEND_TAB1(cfg, true);
- else if (strcmp(optarg, "-append-tab1") == 0)
- ykp_set_tktflag_APPEND_TAB1(cfg, false);
- else if (strcmp(optarg, "append-tab2") == 0)
- ykp_set_tktflag_APPEND_TAB1(cfg, true);
- else if (strcmp(optarg, "-append-tab2") == 0)
- ykp_set_tktflag_APPEND_TAB1(cfg, false);
- else if (strcmp(optarg, "append-delay1") == 0)
- ykp_set_tktflag_APPEND_DELAY1(cfg, true);
- else if (strcmp(optarg, "-append-delay1") == 0)
- ykp_set_tktflag_APPEND_DELAY1(cfg, false);
- else if (strcmp(optarg, "append-delay2") == 0)
- ykp_set_tktflag_APPEND_DELAY2(cfg, true);
- else if (strcmp(optarg, "-append-delay2") == 0)
- ykp_set_tktflag_APPEND_DELAY2(cfg, false);
- else if (strcmp(optarg, "append-cr") == 0)
- ykp_set_tktflag_APPEND_CR(cfg, true);
- else if (strcmp(optarg, "-append-cr") == 0)
- ykp_set_tktflag_APPEND_CR(cfg, false);
- else if (strcmp(optarg, "protect-cfg2") == 0)
- ykp_set_tktflag_PROTECT_CFG2(cfg, true);
- else if (strcmp(optarg, "-protect-cfg2") == 0)
- ykp_set_tktflag_PROTECT_CFG2(cfg, false);
- else if (strcmp(optarg, "send-ref") == 0)
- ykp_set_cfgflag_SEND_REF(cfg, true);
- else if (strcmp(optarg, "-send-ref") == 0)
- ykp_set_cfgflag_SEND_REF(cfg, false);
- else if (strcmp(optarg, "ticket-first") == 0)
- ykp_set_cfgflag_TICKET_FIRST(cfg, true);
- else if (strcmp(optarg, "-ticket-first") == 0)
- ykp_set_cfgflag_TICKET_FIRST(cfg, false);
- else if (strcmp(optarg, "pacing-10ms") == 0)
- ykp_set_cfgflag_PACING_10MS(cfg, true);
- else if (strcmp(optarg, "-pacing-10ms") == 0)
- ykp_set_cfgflag_PACING_10MS(cfg, false);
- else if (strcmp(optarg, "pacing-20ms") == 0)
- ykp_set_cfgflag_PACING_20MS(cfg, true);
- else if (strcmp(optarg, "-pacing-20ms") == 0)
- ykp_set_cfgflag_PACING_20MS(cfg, false);
- else if (strcmp(optarg, "allow-hidtrig") == 0)
- ykp_set_cfgflag_ALLOW_HIDTRIG(cfg, true);
- else if (strcmp(optarg, "-allow-hidtrig") == 0)
- ykp_set_cfgflag_ALLOW_HIDTRIG(cfg, false);
- else if (strcmp(optarg, "static-ticket") == 0)
- ykp_set_cfgflag_STATIC_TICKET(cfg, true);
- else if (strcmp(optarg, "-static-ticket") == 0)
- ykp_set_cfgflag_STATIC_TICKET(cfg, false);
- else if (strcmp(optarg, "short-ticket") == 0)
- ykp_set_cfgflag_SHORT_TICKET(cfg, true);
- else if (strcmp(optarg, "-short-ticket") == 0)
- ykp_set_cfgflag_SHORT_TICKET(cfg, false);
- else if (strcmp(optarg, "strong-pw1") == 0)
- ykp_set_cfgflag_STRONG_PW1(cfg, true);
- else if (strcmp(optarg, "-strong-pw1") == 0)
- ykp_set_cfgflag_STRONG_PW1(cfg, false);
- else if (strcmp(optarg, "strong-pw2") == 0)
- ykp_set_cfgflag_STRONG_PW2(cfg, true);
- else if (strcmp(optarg, "-strong-pw2") == 0)
- ykp_set_cfgflag_STRONG_PW2(cfg, false);
- else if (strcmp(optarg, "man-update") == 0)
- ykp_set_cfgflag_MAN_UPDATE(cfg, true);
- else if (strcmp(optarg, "-man-update") == 0)
- ykp_set_cfgflag_MAN_UPDATE(cfg, false);
+#define TKTFLAG(o, f) \
+ else if (strcmp(optarg, o) == 0) \
+ ykp_set_tktflag_##f(cfg, true); \
+ else if (strcmp(optarg, "-" o) == 0) \
+ ykp_set_tktflag_##f(cfg, false)
+ TKTFLAG("tab-first", TAB_FIRST);
+ TKTFLAG("append-tab1", APPEND_TAB1);
+ TKTFLAG("append-tab2", APPEND_TAB2);
+ TKTFLAG("append-delay1", APPEND_DELAY1);
+ TKTFLAG("append-delay2", APPEND_DELAY2);
+ TKTFLAG("append-cr", APPEND_CR);
+ TKTFLAG("protect-cfg2", PROTECT_CFG2);
+ TKTFLAG("oath-hotp", OATH_HOTP);
+#undef TKTFLAG
+
+#define CFGFLAG(o, f) \
+ else if (strcmp(optarg, o) == 0) \
+ ykp_set_cfgflag_##f(cfg, true); \
+ else if (strcmp(optarg, "-" o) == 0) \
+ ykp_set_cfgflag_##f(cfg, false)
+ CFGFLAG("send-ref", SEND_REF);
+ CFGFLAG("ticket-first", TICKET_FIRST);
+ CFGFLAG("pacing-10ms", PACING_10MS);
+ CFGFLAG("pacing-20ms", PACING_20MS);
+ CFGFLAG("allow-hidtrig", ALLOW_HIDTRIG);
+ CFGFLAG("static-ticket", STATIC_TICKET);
+ CFGFLAG("short-ticket", SHORT_TICKET);
+ CFGFLAG("strong-pw1", STRONG_PW1);
+ CFGFLAG("strong-pw2", STRONG_PW2);
+ CFGFLAG("man-update", MAN_UPDATE);
+ CFGFLAG("oath-hotp8", OATH_HOTP8);
+ CFGFLAG("oath-fixed-modhex1", OATH_FIXED_MODHEX1);
+ CFGFLAG("oath-fixed-modhex2", OATH_FIXED_MODHEX2);
+ CFGFLAG("oath-fixed-modhex", OATH_FIXED_MODHEX);
+#undef CFGFLAG
else {
fprintf(stderr, "Unknown option '%s'\n",
optarg);