1 /* yubikey.h --- Prototypes for low-level YubiKey OTP functions. 2 * 3 * Written by Simon Josefsson <simon@josefsson.org>. 4 * Copyright (c) 2006-2012 Yubico AB 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 */ 32 33 #ifndef YUBIKEY_H 34 #define YUBIKEY_H 35 36 #include <stdint.h> 37 #include <string.h> 38 39 #ifdef __cplusplus 40 extern "C" 41 { 42 #endif 43 44 #define YUBIKEY_BLOCK_SIZE 16 45 #define YUBIKEY_KEY_SIZE 16 46 #define YUBIKEY_UID_SIZE 6 47 #define YUBIKEY_OTP_SIZE (2 * YUBIKEY_BLOCK_SIZE) 48 49 typedef struct 50 { 51 /* Unique (secret) ID. */ 52 uint8_t uid[YUBIKEY_UID_SIZE]; 53 /* Session counter (incremented by 1 at each startup). High bit 54 indicates whether caps-lock triggered the token. */ 55 uint16_t ctr; 56 /* Timestamp incremented by approx 8Hz (low part). */ 57 uint16_t tstpl; 58 /* Timestamp (high part). */ 59 uint8_t tstph; 60 /* Number of times used within session + activation flags. */ 61 uint8_t use; 62 /* Pseudo-random value. */ 63 uint16_t rnd; 64 /* CRC16 value of all fields. */ 65 uint16_t crc; 66 } yubikey_token_st; 67 68 typedef yubikey_token_st *yubikey_token_t; 69 70 /* High-level functions. */ 71 72 73 /* Decrypt TOKEN using KEY and store output in OUT structure. Note 74 that there is no error checking whether the output data is valid or 75 not, use yubikey_check_* for that. */ 76 extern void yubikey_parse (const uint8_t token[YUBIKEY_BLOCK_SIZE], 77 const uint8_t key[YUBIKEY_KEY_SIZE], 78 yubikey_token_t out); 79 80 /* Generate OTP */ 81 extern void yubikey_generate (yubikey_token_t token, 82 const uint8_t key[YUBIKEY_KEY_SIZE], 83 char out[YUBIKEY_OTP_SIZE]); 84 85 #define yubikey_counter(ctr) ((ctr) & 0x7FFF) 86 #define yubikey_capslock(ctr) ((ctr) & 0x8000) 87 #define yubikey_crc_ok_p(tok) \ 88 (yubikey_crc16 ((tok), YUBIKEY_BLOCK_SIZE) == YUBIKEY_CRC_OK_RESIDUE) 89 90 /* 91 * Low-level functions; ModHex. 92 */ 93 94 #define YUBIKEY_MODHEX_MAP "cbdefghijklnrtuv" 95 96 /* ModHex encode input string SRC of length SRCSIZE and put the zero 97 terminated output string in DST. The size of the output string DST 98 must be at least 2*SRCSIZE+1. The output string is always 99 2*SRCSIZE large plus the terminating zero. */ 100 extern void yubikey_modhex_encode (char *dst, 101 const char *src, size_t srcsize); 102 103 /* ModHex decode input string SRC of length DSTSIZE/2 into output 104 string DST. The output string DST is always DSTSIZE/2 large plus 105 the terminating zero. */ 106 extern void yubikey_modhex_decode (char *dst, 107 const char *src, size_t dstsize); 108 109 /* Hex encode/decode data, same interface as modhex functions. */ 110 extern void yubikey_hex_encode (char *dst, const char *src, size_t srcsize); 111 extern void yubikey_hex_decode (char *dst, const char *src, size_t dstsize); 112 113 /* Return non-zero if zero-terminated input STR is a valid (mod)hex 114 string, and zero if any non-alphabetic characters are found. */ 115 extern int yubikey_modhex_p (const char *str); 116 extern int yubikey_hex_p (const char *str); 117 118 /* 119 * Low-level functions; CRC. 120 */ 121 122 #define YUBIKEY_CRC_OK_RESIDUE 0xf0b8 123 extern uint16_t yubikey_crc16 (const uint8_t * buf, size_t buf_size); 124 125 /* Low-level functions; AES. */ 126 127 /* AES-decrypt/encrypt one 16-byte block STATE using the 128-bit KEY, 128 leaving the decrypted/encrypted output in the STATE buffer. */ 129 extern void yubikey_aes_decrypt (uint8_t * state, const uint8_t * key); 130 extern void yubikey_aes_encrypt (uint8_t * state, const uint8_t * key); 131 132 #ifdef __cplusplus 133 } 134 #endif 135 136 #endif 137