···1+/* sha1.c - Functions to compute SHA1 message digest of files or
2+ memory blocks according to the NIST specification FIPS-180-1.
3+4+ Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006 Free Software
5+ Foundation, Inc.
6+7+ This program is free software; you can redistribute it and/or modify it
8+ under the terms of the GNU General Public License as published by the
9+ Free Software Foundation; either version 2, or (at your option) any
10+ later version.
11+12+ This program is distributed in the hope that it will be useful,
13+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ GNU General Public License for more details.
16+17+ You should have received a copy of the GNU General Public License
18+ along with this program; if not, write to the Free Software Foundation,
19+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20+21+/* Written by Scott G. Miller
22+ Credits:
23+ Robert Klep <robert@ilse.nl> -- Expansion function fix
24+*/
25+26+#include "plugin.h"
27+#include "sha1.h"
28+29+#ifdef WORDS_BIGENDIAN
30+# define SWAP(n) (n)
31+#else
32+# define SWAP(n) \
33+ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
34+#endif
35+36+#define BLOCKSIZE 4096
37+#if BLOCKSIZE % 64 != 0
38+# error "invalid BLOCKSIZE"
39+#endif
40+41+/* This array contains the bytes used to pad the buffer to the next
42+ 64-byte boundary. (RFC 1321, 3.1: Step 1) */
43+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
44+45+46+/* Take a pointer to a 160 bit block of data (five 32 bit ints) and
47+ initialize it to the start constants of the SHA1 algorithm. This
48+ must be called before using hash in the call to sha1_hash. */
49+void
50+sha1_init_ctx (struct sha1_ctx *ctx)
51+{
52+ ctx->A = 0x67452301;
53+ ctx->B = 0xefcdab89;
54+ ctx->C = 0x98badcfe;
55+ ctx->D = 0x10325476;
56+ ctx->E = 0xc3d2e1f0;
57+58+ ctx->total[0] = ctx->total[1] = 0;
59+ ctx->buflen = 0;
60+}
61+62+/* Put result from CTX in first 20 bytes following RESBUF. The result
63+ must be in little endian byte order.
64+65+ IMPORTANT: On some systems it is required that RESBUF is correctly
66+ aligned for a 32-bit value. */
67+void *
68+sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
69+{
70+ ((uint32_t *) resbuf)[0] = SWAP (ctx->A);
71+ ((uint32_t *) resbuf)[1] = SWAP (ctx->B);
72+ ((uint32_t *) resbuf)[2] = SWAP (ctx->C);
73+ ((uint32_t *) resbuf)[3] = SWAP (ctx->D);
74+ ((uint32_t *) resbuf)[4] = SWAP (ctx->E);
75+76+ return resbuf;
77+}
78+79+/* Process the remaining bytes in the internal buffer and the usual
80+ prolog according to the standard and write the result to RESBUF.
81+82+ IMPORTANT: On some systems it is required that RESBUF is correctly
83+ aligned for a 32-bit value. */
84+void *
85+sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
86+{
87+ /* Take yet unprocessed bytes into account. */
88+ uint32_t bytes = ctx->buflen;
89+ size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
90+91+ /* Now count remaining bytes. */
92+ ctx->total[0] += bytes;
93+ if (ctx->total[0] < bytes)
94+ ++ctx->total[1];
95+96+ /* Put the 64-bit file length in *bits* at the end of the buffer. */
97+ ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
98+ ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3);
99+100+ memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
101+102+ /* Process last bytes. */
103+ sha1_process_block (ctx->buffer, size * 4, ctx);
104+105+ return sha1_read_ctx (ctx, resbuf);
106+}
107+108+/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
109+ result is always in little endian byte order, so that a byte-wise
110+ output yields to the wanted ASCII representation of the message
111+ digest. */
112+void *sha1_buffer (const char *buffer, size_t len, void *resblock)
113+{
114+ struct sha1_ctx ctx;
115+116+ /* Initialize the computation context. */
117+ sha1_init_ctx (&ctx);
118+119+ /* Process whole buffer but last len % 64 bytes. */
120+ sha1_process_bytes (buffer, len, &ctx);
121+122+ /* Put result in desired memory area. */
123+ return sha1_finish_ctx (&ctx, resblock);
124+}
125+126+void
127+sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
128+{
129+ /* When we already have some bits in our internal buffer concatenate
130+ both inputs first. */
131+ if (ctx->buflen != 0)
132+ {
133+ size_t left_over = ctx->buflen;
134+ size_t add = 128 - left_over > len ? len : 128 - left_over;
135+136+ memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
137+ ctx->buflen += add;
138+139+ if (ctx->buflen > 64)
140+ {
141+ sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
142+143+ ctx->buflen &= 63;
144+ /* The regions in the following copy operation cannot overlap. */
145+ memcpy (ctx->buffer,
146+ &((char *) ctx->buffer)[(left_over + add) & ~63],
147+ ctx->buflen);
148+ }
149+150+ buffer = (const char *) buffer + add;
151+ len -= add;
152+ }
153+154+ /* Process available complete blocks. */
155+ if (len >= 64)
156+ {
157+ {
158+ sha1_process_block (buffer, len & ~63, ctx);
159+ buffer = (const char *) buffer + (len & ~63);
160+ len &= 63;
161+ }
162+ }
163+164+ /* Move remaining bytes in internal buffer. */
165+ if (len > 0)
166+ {
167+ size_t left_over = ctx->buflen;
168+169+ memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
170+ left_over += len;
171+ if (left_over >= 64)
172+ {
173+ sha1_process_block (ctx->buffer, 64, ctx);
174+ left_over -= 64;
175+ memcpy (ctx->buffer, &ctx->buffer[16], left_over);
176+ }
177+ ctx->buflen = left_over;
178+ }
179+}
180+181+/* --- Code below is the primary difference between md5.c and sha1.c --- */
182+183+/* SHA1 round constants */
184+#define K1 0x5a827999
185+#define K2 0x6ed9eba1
186+#define K3 0x8f1bbcdc
187+#define K4 0xca62c1d6
188+189+/* Round functions. Note that F2 is the same as F4. */
190+#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
191+#define F2(B,C,D) (B ^ C ^ D)
192+#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
193+#define F4(B,C,D) (B ^ C ^ D)
194+195+/* Process LEN bytes of BUFFER, accumulating context into CTX.
196+ It is assumed that LEN % 64 == 0.
197+ Most of this code comes from GnuPG's cipher/sha1.c. */
198+199+void
200+sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
201+{
202+ const uint32_t *words = buffer;
203+ size_t nwords = len / sizeof (uint32_t);
204+ const uint32_t *endp = words + nwords;
205+ uint32_t x[16];
206+ uint32_t a = ctx->A;
207+ uint32_t b = ctx->B;
208+ uint32_t c = ctx->C;
209+ uint32_t d = ctx->D;
210+ uint32_t e = ctx->E;
211+212+ /* First increment the byte count. RFC 1321 specifies the possible
213+ length of the file up to 2^64 bits. Here we only compute the
214+ number of bytes. Do a double word increment. */
215+ ctx->total[0] += len;
216+ if (ctx->total[0] < len)
217+ ++ctx->total[1];
218+219+#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n))))
220+221+#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \
222+ ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
223+ , (x[I&0x0f] = rol(tm, 1)) )
224+225+#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \
226+ + F( B, C, D ) \
227+ + K \
228+ + M; \
229+ B = rol( B, 30 ); \
230+ } while(0)
231+232+ while (words < endp)
233+ {
234+ uint32_t tm;
235+ int t;
236+ for (t = 0; t < 16; t++)
237+ {
238+ x[t] = SWAP (*words);
239+ words++;
240+ }
241+242+ R( a, b, c, d, e, F1, K1, x[ 0] );
243+ R( e, a, b, c, d, F1, K1, x[ 1] );
244+ R( d, e, a, b, c, F1, K1, x[ 2] );
245+ R( c, d, e, a, b, F1, K1, x[ 3] );
246+ R( b, c, d, e, a, F1, K1, x[ 4] );
247+ R( a, b, c, d, e, F1, K1, x[ 5] );
248+ R( e, a, b, c, d, F1, K1, x[ 6] );
249+ R( d, e, a, b, c, F1, K1, x[ 7] );
250+ R( c, d, e, a, b, F1, K1, x[ 8] );
251+ R( b, c, d, e, a, F1, K1, x[ 9] );
252+ R( a, b, c, d, e, F1, K1, x[10] );
253+ R( e, a, b, c, d, F1, K1, x[11] );
254+ R( d, e, a, b, c, F1, K1, x[12] );
255+ R( c, d, e, a, b, F1, K1, x[13] );
256+ R( b, c, d, e, a, F1, K1, x[14] );
257+ R( a, b, c, d, e, F1, K1, x[15] );
258+ R( e, a, b, c, d, F1, K1, M(16) );
259+ R( d, e, a, b, c, F1, K1, M(17) );
260+ R( c, d, e, a, b, F1, K1, M(18) );
261+ R( b, c, d, e, a, F1, K1, M(19) );
262+ R( a, b, c, d, e, F2, K2, M(20) );
263+ R( e, a, b, c, d, F2, K2, M(21) );
264+ R( d, e, a, b, c, F2, K2, M(22) );
265+ R( c, d, e, a, b, F2, K2, M(23) );
266+ R( b, c, d, e, a, F2, K2, M(24) );
267+ R( a, b, c, d, e, F2, K2, M(25) );
268+ R( e, a, b, c, d, F2, K2, M(26) );
269+ R( d, e, a, b, c, F2, K2, M(27) );
270+ R( c, d, e, a, b, F2, K2, M(28) );
271+ R( b, c, d, e, a, F2, K2, M(29) );
272+ R( a, b, c, d, e, F2, K2, M(30) );
273+ R( e, a, b, c, d, F2, K2, M(31) );
274+ R( d, e, a, b, c, F2, K2, M(32) );
275+ R( c, d, e, a, b, F2, K2, M(33) );
276+ R( b, c, d, e, a, F2, K2, M(34) );
277+ R( a, b, c, d, e, F2, K2, M(35) );
278+ R( e, a, b, c, d, F2, K2, M(36) );
279+ R( d, e, a, b, c, F2, K2, M(37) );
280+ R( c, d, e, a, b, F2, K2, M(38) );
281+ R( b, c, d, e, a, F2, K2, M(39) );
282+ R( a, b, c, d, e, F3, K3, M(40) );
283+ R( e, a, b, c, d, F3, K3, M(41) );
284+ R( d, e, a, b, c, F3, K3, M(42) );
285+ R( c, d, e, a, b, F3, K3, M(43) );
286+ R( b, c, d, e, a, F3, K3, M(44) );
287+ R( a, b, c, d, e, F3, K3, M(45) );
288+ R( e, a, b, c, d, F3, K3, M(46) );
289+ R( d, e, a, b, c, F3, K3, M(47) );
290+ R( c, d, e, a, b, F3, K3, M(48) );
291+ R( b, c, d, e, a, F3, K3, M(49) );
292+ R( a, b, c, d, e, F3, K3, M(50) );
293+ R( e, a, b, c, d, F3, K3, M(51) );
294+ R( d, e, a, b, c, F3, K3, M(52) );
295+ R( c, d, e, a, b, F3, K3, M(53) );
296+ R( b, c, d, e, a, F3, K3, M(54) );
297+ R( a, b, c, d, e, F3, K3, M(55) );
298+ R( e, a, b, c, d, F3, K3, M(56) );
299+ R( d, e, a, b, c, F3, K3, M(57) );
300+ R( c, d, e, a, b, F3, K3, M(58) );
301+ R( b, c, d, e, a, F3, K3, M(59) );
302+ R( a, b, c, d, e, F4, K4, M(60) );
303+ R( e, a, b, c, d, F4, K4, M(61) );
304+ R( d, e, a, b, c, F4, K4, M(62) );
305+ R( c, d, e, a, b, F4, K4, M(63) );
306+ R( b, c, d, e, a, F4, K4, M(64) );
307+ R( a, b, c, d, e, F4, K4, M(65) );
308+ R( e, a, b, c, d, F4, K4, M(66) );
309+ R( d, e, a, b, c, F4, K4, M(67) );
310+ R( c, d, e, a, b, F4, K4, M(68) );
311+ R( b, c, d, e, a, F4, K4, M(69) );
312+ R( a, b, c, d, e, F4, K4, M(70) );
313+ R( e, a, b, c, d, F4, K4, M(71) );
314+ R( d, e, a, b, c, F4, K4, M(72) );
315+ R( c, d, e, a, b, F4, K4, M(73) );
316+ R( b, c, d, e, a, F4, K4, M(74) );
317+ R( a, b, c, d, e, F4, K4, M(75) );
318+ R( e, a, b, c, d, F4, K4, M(76) );
319+ R( d, e, a, b, c, F4, K4, M(77) );
320+ R( c, d, e, a, b, F4, K4, M(78) );
321+ R( b, c, d, e, a, F4, K4, M(79) );
322+323+ a = ctx->A += a;
324+ b = ctx->B += b;
325+ c = ctx->C += c;
326+ d = ctx->D += d;
327+ e = ctx->E += e;
328+ }
329+}
330+331+/* memxor.c -- perform binary exclusive OR operation of two memory blocks.
332+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
333+334+ This program is free software; you can redistribute it and/or modify
335+ it under the terms of the GNU General Public License as published by
336+ the Free Software Foundation; either version 2, or (at your option)
337+ any later version.
338+339+ This program is distributed in the hope that it will be useful,
340+ but WITHOUT ANY WARRANTY; without even the implied warranty of
341+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
342+ GNU General Public License for more details.
343+344+ You should have received a copy of the GNU General Public License
345+ along with this program; if not, write to the Free Software Foundation,
346+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
347+348+/* Written by Simon Josefsson. The interface was inspired by memxor
349+ in Niels Möller's Nettle. */
350+351+void *
352+memxor (void * dest, const void * src, size_t n)
353+{
354+ char const *s = src;
355+ char *d = dest;
356+357+ for (; n > 0; n--)
358+ *d++ ^= *s++;
359+360+ return dest;
361+}
362+363+/* hmac-sha1.c -- hashed message authentication codes
364+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
365+366+ This program is free software; you can redistribute it and/or modify
367+ it under the terms of the GNU General Public License as published by
368+ the Free Software Foundation; either version 2, or (at your option)
369+ any later version.
370+371+ This program is distributed in the hope that it will be useful,
372+ but WITHOUT ANY WARRANTY; without even the implied warranty of
373+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
374+ GNU General Public License for more details.
375+376+ You should have received a copy of the GNU General Public License
377+ along with this program; if not, write to the Free Software Foundation,
378+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
379+380+/* Written by Simon Josefsson. */
381+382+#define IPAD 0x36
383+#define OPAD 0x5c
384+385+int
386+hmac_sha1 (const void *key, size_t keylen,
387+ const void *in, size_t inlen, void *resbuf)
388+{
389+ struct sha1_ctx inner;
390+ struct sha1_ctx outer;
391+ char optkeybuf[20];
392+ char block[64];
393+ char innerhash[20];
394+395+ /* Reduce the key's size, so that it becomes <= 64 bytes large. */
396+397+ if (keylen > 64)
398+ {
399+ struct sha1_ctx keyhash;
400+401+ sha1_init_ctx (&keyhash);
402+ sha1_process_bytes (key, keylen, &keyhash);
403+ sha1_finish_ctx (&keyhash, optkeybuf);
404+405+ key = optkeybuf;
406+ keylen = 20;
407+ }
408+409+ /* Compute INNERHASH from KEY and IN. */
410+411+ sha1_init_ctx (&inner);
412+413+ memset (block, IPAD, sizeof (block));
414+ memxor (block, key, keylen);
415+416+ sha1_process_block (block, 64, &inner);
417+ sha1_process_bytes (in, inlen, &inner);
418+419+ sha1_finish_ctx (&inner, innerhash);
420+421+ /* Compute result from KEY and INNERHASH. */
422+423+ sha1_init_ctx (&outer);
424+425+ memset (block, OPAD, sizeof (block));
426+ memxor (block, key, keylen);
427+428+ sha1_process_block (block, 64, &outer);
429+ sha1_process_bytes (innerhash, 20, &outer);
430+431+ sha1_finish_ctx (&outer, resbuf);
432+433+ return 0;
434+}
···1+/* Taken from gnulib (http://savannah.gnu.org/projects/gnulib/) */
2+/* Declarations of functions and data types used for SHA1 sum
3+ library functions.
4+ Copyright (C) 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
5+6+ This program is free software; you can redistribute it and/or modify it
7+ under the terms of the GNU General Public License as published by the
8+ Free Software Foundation; either version 2, or (at your option) any
9+ later version.
10+11+ This program is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ GNU General Public License for more details.
15+16+ You should have received a copy of the GNU General Public License
17+ along with this program; if not, write to the Free Software Foundation,
18+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19+20+#ifndef SHA1_H
21+#define SHA1_H 1
22+23+#include "plugin.h"
24+25+/* Structure to save state of computation between the single steps. */
26+struct sha1_ctx
27+{
28+ uint32_t A;
29+ uint32_t B;
30+ uint32_t C;
31+ uint32_t D;
32+ uint32_t E;
33+34+ uint32_t total[2];
35+ uint32_t buflen;
36+ uint32_t buffer[32];
37+};
38+39+40+/* Initialize structure containing state of computation. */
41+void sha1_init_ctx (struct sha1_ctx *ctx);
42+43+/* Starting with the result of former calls of this function (or the
44+ initialization function update the context for the next LEN bytes
45+ starting at BUFFER.
46+ It is necessary that LEN is a multiple of 64!!! */
47+void sha1_process_block (const void *buffer, size_t len,
48+ struct sha1_ctx *ctx);
49+50+/* Starting with the result of former calls of this function (or the
51+ initialization function update the context for the next LEN bytes
52+ starting at BUFFER.
53+ It is NOT required that LEN is a multiple of 64. */
54+void sha1_process_bytes (const void *buffer, size_t len,
55+ struct sha1_ctx *ctx);
56+57+/* Process the remaining bytes in the buffer and put result from CTX
58+ in first 20 bytes following RESBUF. The result is always in little
59+ endian byte order, so that a byte-wise output yields to the wanted
60+ ASCII representation of the message digest.
61+62+ IMPORTANT: On some systems it is required that RESBUF be correctly
63+ aligned for a 32 bits value. */
64+void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
65+66+67+/* Put result from CTX in first 20 bytes following RESBUF. The result is
68+ always in little endian byte order, so that a byte-wise output yields
69+ to the wanted ASCII representation of the message digest.
70+71+ IMPORTANT: On some systems it is required that RESBUF is correctly
72+ aligned for a 32 bits value. */
73+void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
74+75+/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
76+ result is always in little endian byte order, so that a byte-wise
77+ output yields to the wanted ASCII representation of the message
78+ digest. */
79+void *sha1_buffer (const char *buffer, size_t len, void *resblock);
80+81+#endif
82+83+84+/* hmac.h -- hashed message authentication codes
85+ Copyright (C) 2005 Free Software Foundation, Inc.
86+87+ This program is free software; you can redistribute it and/or modify
88+ it under the terms of the GNU General Public License as published by
89+ the Free Software Foundation; either version 2, or (at your option)
90+ any later version.
91+92+ This program is distributed in the hope that it will be useful,
93+ but WITHOUT ANY WARRANTY; without even the implied warranty of
94+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
95+ GNU General Public License for more details.
96+97+ You should have received a copy of the GNU General Public License
98+ along with this program; if not, write to the Free Software Foundation,
99+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
100+101+/* Written by Simon Josefsson. */
102+103+#ifndef HMAC_H
104+#define HMAC_H 1
105+106+#include <stddef.h>
107+108+/* Compute Hashed Message Authentication Code with SHA-1, over BUFFER
109+ data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
110+ output to pre-allocated 20 byte minimum RESBUF buffer. Return 0 on
111+ success. */
112+int
113+hmac_sha1 (const void *key, size_t keylen,
114+ const void *in, size_t inlen, void *resbuf);
115+116+#endif /* HMAC_H */
···1% $Id:$ %
2003Time related menu options. Pressing \ActionStdContext{} will voice the current time
4if voice support is enabled.
5
···1% $Id:$ %
23+\label{ref:Timeanddateactual}
4+5Time related menu options. Pressing \ActionStdContext{} will voice the current time
6if voice support is enabled.
7
···1+% $Id$ %
2+\subsection{One-Time Password Client}
3+This plugin provides the ability to generate one-time passwords (OTPs)
4+for authentication purposes. It implements an HMAC-based One-Time
5+Password Algorithm (RFC 4226), and on targets which support it, a
6+Time-based One-Time Password Algorithm (RFC 6238).
7+8+\subsubsection{Adding Accounts}
9+The plugin supports two methods of adding accounts: URI import, and
10+manual entry.
11+12+\opt{rtc}{ It is important to note that for TOTP (time-based) accounts
13+ to work properly, the clock on your device MUST be accurate to no
14+ less than 30 seconds from the time on the authentication server, and
15+ the correct time zone must be configured in the plugin. See
16+ \reference{ref:Timeanddateactual} for more information. }
17+18+\subsubsection{URI Import}
19+This method of adding an account reads a list of URIs from a file. It
20+expects each URI to be on a line by itself in the following format:
21+22+\begin{verbatim}
23+otpauth://[hotp OR totp]/[account name]?secret=[Base32 secret][&counter=X][&period=X][&digits=X]
24+\end{verbatim}
25+26+An example is shown below, provisioning a TOTP key for an account called ``bob'':
27+28+\begin{verbatim}
29+otpauth://totp/bob?secret=JBSWY3DPEHPK3PXP
30+\end{verbatim}
31+32+Any other URI options are not supported and will be ignored.
33+34+Most services will provide a scannable QR code that encodes a OTP
35+URI. In order to use those, first scan the QR code separately and save
36+the URI to a file on your device. If necessary, rewrite the URI so it
37+is in the format shown above. For example, GitHub's URI has a slash
38+after the provider. In order for this URI to be properly parsed, you
39+must rewrite the account name so that it does not contain a slash.
40+41+\subsubsection{Manual Import}
42+If direct URI import is not possible, the plugin supports the manual
43+entry of data associated with an account. After you select the
44+``Manual Entry'' option, it will prompt you for an account name. You
45+may type anything you wish, but it should be memorable. It will then
46+prompt you for the Base32-encoded secret. Most services will provide
47+this to you directly, but some may only provide you with a QR code. In
48+these cases, you must scan the QR code separately, and then enter the
49+string following the ``secret='' parameter on your Rockbox device
50+manually.
51+52+On devices with a real-time clock, \opt{rtc}{like yours,} the plugin
53+will ask whether the account is a time-based account
54+(TOTP). \opt{rtc}{If you answer ``yes'' to this question, it will ask
55+ for further information regarding the account. Usually it is safe to
56+ accept the defaults here. } However, if your device lacks a
57+real-time clock, the plugin's functionality will be restricted to
58+HMAC-based (HOTP) accounts only. If this is the case, the plugin will
59+prompt you for information regarding the HOTP setup.
60+61+\opt{rtc} {
62+ \subsection{Advanced Settings}
63+ \subsubsection{Time Zone Configuration}
64+ In order for TOTP accounts to work properly, the plugin must be able
65+ to determine the current UTC time. This means that, first, your
66+ device's clock must be synchronized with UTC time, and second, that
67+ the plugin knows what time zone the clock is using. The plugin will
68+ prompt you on its first run for this piece of information. However,
69+ should this setting need changing at a later time, possibly due to
70+ Daylight Saving Time adjustment, it is located under the
71+ ``Advanced'' submenu. NOTE: in the UI simulator, use the ``UTC''
72+ setting no matter what the clock may read. }