util.h (3130B)
1 #ifndef UTIL_H 2 #define UTIL_H 3 4 #include <stdlib.h> 5 #include <stddef.h> 6 #include <stdint.h> 7 #include <string.h> 8 #include <time.h> 9 10 enum totp_error { 11 TOTP_EEOF = -2, 12 TOTP_EMALF, 13 TOTP_EMAX, 14 15 TOTP_EMIN = TOTP_EEOF, 16 }; 17 18 struct bytes { 19 uint8_t *data; 20 uint8_t *end; 21 }; 22 23 typedef void (*digest_init)(void *c); 24 typedef void (*digest_update)(void *c, const void *data, size_t len); 25 typedef void (*digest_finish)(void *c); 26 27 void xormem(void *a, const void *b, size_t len); 28 void randmem(void *a, size_t len); 29 void hmac(const void *key, size_t keylen, 30 const void *data, size_t datalen, 31 digest_init init, 32 digest_update update, 33 digest_finish finish, 34 size_t ctxsz, 35 size_t blocksz, 36 size_t digestsz, 37 ptrdiff_t buf_off, 38 ptrdiff_t digest_off, 39 void *h); 40 41 uint32_t totp(const void *key, size_t keylen, 42 time_t t1, uint8_t period, 43 time_t t0, 44 void (*hmac_f)(const void *key, size_t keylen, 45 const void *data, size_t datalen, 46 void *h), size_t hshsz); 47 48 uint32_t hotp(const void *key, size_t keylen, 49 const void *counter, size_t counterlen, 50 void (*hmac_f)(const void *key, size_t keylen, 51 const void *data, size_t datalen, 52 void *h), size_t hshsz); 53 54 size_t strncspn(const char *haystack, size_t haystacklen, const char *needles); 55 56 static inline void *writebeu32(void *dest, uint32_t v) 57 { 58 uint8_t *buffer = dest; 59 *buffer++ = v >> 24; 60 *buffer++ = v >> 16; 61 *buffer++ = v >> 8; 62 *buffer++ = v; 63 return buffer; 64 } 65 66 static inline void *writebeu64(void *dest, uint64_t v) 67 { 68 uint8_t *buffer = dest; 69 *buffer++ = v >> 56; 70 *buffer++ = v >> 48; 71 *buffer++ = v >> 40; 72 *buffer++ = v >> 32; 73 *buffer++ = v >> 24; 74 *buffer++ = v >> 16; 75 *buffer++ = v >> 8; 76 *buffer++ = v; 77 return buffer; 78 } 79 80 static inline uint64_t readbeu64(const void *src) 81 { 82 const uint8_t *buffer = src; 83 return (uint64_t)buffer[0] << 56 | 84 (uint64_t)buffer[1] << 48 | 85 (uint64_t)buffer[2] << 40 | 86 (uint64_t)buffer[3] << 32 | 87 (uint64_t)buffer[4] << 24 | 88 (uint64_t)buffer[5] << 16 | 89 (uint64_t)buffer[6] << 8 | 90 (uint64_t)buffer[7]; 91 } 92 93 static inline void *mempush(void *dst, const void *src, size_t n) 94 { 95 if (n) 96 memcpy(dst, src, n); 97 return (char *)dst + n; 98 } 99 100 static inline void *mempushb(void *dst, struct bytes data) 101 { 102 return mempush(dst, data.data, data.end - data.data); 103 } 104 105 static inline int bytesequal(struct bytes a, struct bytes b) 106 { 107 return a.end - a.data == b.end - b.data && !memcmp(a.data, b.data, a.end - a.data); 108 } 109 110 static inline char *if_prefix(const char *s, const char *prefix) 111 { 112 while (*prefix) 113 if (*s++ != *prefix++) 114 return NULL; 115 return (char *)s; 116 } 117 118 const char *totp_strerror(int err); 119 void croak(const char *fmt, ...); 120 struct bytes debase32(struct bytes data); 121 122 static inline ptrdiff_t pdiff(const void *a, const void *b) { 123 return (const char *)b - (const char *)a; 124 } 125 126 static inline struct bytes bytesec(void *data, void *end) 127 { 128 return (struct bytes){ data, end }; 129 } 130 131 static inline struct bytes bytesnc(void *data, size_t n) 132 { 133 return (struct bytes){ data, (uint8_t *)data + n }; 134 } 135 136 static inline ptrdiff_t bytes_len(struct bytes bytes) { 137 return bytes.end - bytes.data; 138 } 139 140 #endif