-
Notifications
You must be signed in to change notification settings - Fork 2
/
hotp.h
54 lines (43 loc) · 1.13 KB
/
hotp.h
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
/*
* RFC 4226
*/
#ifndef HOTP_H
#define HOTP_H
#include <stdlib.h>
#include <math.h>
#include "hmac.h"
typedef struct {
uint64_t counter;
const uint8_t* secret;
size_t secretSize;
void* (*hashFn)(const void*, size_t);
size_t blockSize;
size_t outputLength;
} hotp_context;
uint32_t hotp_DT(const uint8_t* data, size_t len) {
uint8_t offset = data[len - 1] & 0x0f;
uint32_t p = (data[offset] & 0x7f) << 24
| data[offset + 1] << 16
| data[offset + 2] << 8
| data[offset + 3];
return p;
}
uint32_t hotp(hotp_context *ctx, uint8_t digits) {
if (!ctx) {
return 0;
}
uint8_t counter[8];
counter[0] = ctx->counter >> 56;
counter[1] = ctx->counter >> 48;
counter[2] = ctx->counter >> 40;
counter[3] = ctx->counter >> 32;
counter[4] = ctx->counter >> 24;
counter[5] = ctx->counter >> 16;
counter[6] = ctx->counter >> 8;
counter[7] = ctx->counter;
uint8_t* hs = hmac(counter, sizeof(counter), ctx->secret, ctx->secretSize, ctx->hashFn, ctx->blockSize, ctx->outputLength);
uint32_t Snum = hotp_DT(hs, ctx->outputLength);
free(hs);
return Snum % (uint32_t) pow(10.0, digits);
}
#endif