DSL
hmac.cpp
1 //@AUTOHEADER@BEGIN@
2 /***********************************************************************\
3 | Drift Standard Libraries v1.01 |
4 | Copyright 2010-2023 Drift Solutions / Indy Sams |
5 | Docs and more information available at https://www.driftsolutions.dev |
6 | This file released under the 3-clause BSD license, |
7 | see included DSL.LICENSE.TXT file for details. |
8 \***********************************************************************/
9 //@AUTOHEADER@END@
10 
11 #include <drift/dslcore.h>
12 #include <drift/GenLib.h>
13 #include <drift/Mutex.h>
14 #include <drift/hash.h>
15 #include <drift/hmac.h>
16 
17 extern DSL_Mutex * dslMutex();
18 
19 typedef vector<const HMAC_PROVIDER*> hmacProviderList;
20 hmacProviderList* dslHMACProviders() {
21  AutoMutexPtr(dslMutex());
22  static hmacProviderList hmac_providers { &dsl_native_hmacers };
23  return &hmac_providers;
24 }
25 
26 void DSL_CC dsl_add_hmac_provider(const HMAC_PROVIDER * p) {
27  AutoMutexPtr(dslMutex());
28  hmacProviderList* hmac_providers = dslHMACProviders();
29  hmac_providers->insert(hmac_providers->begin(), p);
30 }
31 void DSL_CC dsl_remove_hmac_provider(const HMAC_PROVIDER * p) {
32  AutoMutexPtr(dslMutex());
33  hmacProviderList* hmac_providers = dslHMACProviders();
34  for (auto x = hmac_providers->begin(); x != hmac_providers->end(); x++) {
35  if (*x == p) {
36  hmac_providers->erase(x);
37  break;
38  }
39  }
40 }
41 void DSL_CC dsl_get_hmac_providers(vector<const HMAC_PROVIDER *>& p) {
42  AutoMutexPtr(dslMutex());
43  p = *dslHMACProviders();
44 }
45 
46 
47 HASH_HMAC_CTX * DSL_CC hmac_init(const char * name, const uint8 *key, size_t length) {
48  hmacProviderList* hmac_providers = dslHMACProviders();
49  for (auto x = hmac_providers->begin(); x != hmac_providers->end(); x++) {
50  HASH_HMAC_CTX * ret = (*x)->hmac_init(name, key, length);
51  if (ret != NULL) {
52  ret->provider = *x;
53  return ret;
54  }
55  }
56  return NULL;
57 }
58 
59 void DSL_CC hmac_update(HASH_HMAC_CTX *ctx, const uint8 *data, size_t len) {
60  if (ctx == NULL || data == NULL) {
61  return;
62  }
63  ctx->provider->hmac_update(ctx, data, len);
64 }
65 
66 bool DSL_CC hmac_finish(HASH_HMAC_CTX *ctx, uint8 * out, size_t outlen) {
67  if (ctx == NULL || out == NULL) {
68  return false;
69  }
70  return ctx->provider->hmac_finish(ctx, out, outlen);
71 }
72 
73 DSL_API bool DSL_CC hmacdata(const char * name, const uint8 *key, size_t keylen, const uint8 *data, size_t datalen, char * out, size_t outlen) {
74  HASH_HMAC_CTX * ctx = hmac_init(name, key, keylen);
75  if (ctx == NULL) {
76  return false;
77  }
78  if (outlen < ((ctx->hashSize*2)+1)) {
79  return false;
80  }
81 
82  hmac_update(ctx,data,datalen);
83 
84  size_t size = ctx->hashSize;
85  unsigned char * hashtmp = (unsigned char *)dsl_malloc(size);
86  bool ret = hmac_finish(ctx, hashtmp, size);
87  if (ret) {
88  ret = (bin2hex(hashtmp, size, out, outlen) != NULL);
89  }
90  dsl_free(hashtmp);
91  return ret;
92 }
93 
94 DSL_API bool DSL_CC hmacfile(const char * name, const uint8 *key, size_t keylen, const char * fn, char * out, size_t outlen) {
95  DSL_FILE * fp = RW_OpenFile(fn, "rb");
96  if (fp) {
97  bool ret = hmacfile_rw(name, key, keylen, fp, out, outlen);
98  fp->close(fp);
99  return ret;
100  }
101  return false;
102 }
103 
104 DSL_API bool DSL_CC hmacfile_fp(const char * name, const uint8 *key, size_t keylen, FILE * fpp, char * out, size_t outlen) {
105  if (fpp == NULL) { return false; }
106 
107  DSL_FILE * fp = RW_ConvertFile(fpp, false);
108  if (fp) {
109  bool ret = hmacfile_rw(name, key, keylen, fp, out, outlen);
110  fp->close(fp);
111  return ret;
112  }
113  return false;
114 }
115 
116 DSL_API bool DSL_CC hmacfile_rw(const char * name, const uint8 *key, size_t keylen, DSL_FILE * fp, char * out, size_t outlen) {
117  HASH_HMAC_CTX * ctx = hmac_init(name, key, keylen);
118  if (ctx == NULL) {
119  return false;
120  }
121  if (outlen < ((ctx->hashSize*2)+1)) {
122  return false;
123  }
124 
125  char buf[32768];
126 
127  fp->seek(fp, 0, SEEK_END);
128  int64 left = fp->tell(fp);
129  fp->seek(fp, 0, SEEK_SET);
130 
131  bool ret = true;
132  while (left) {
133  int64 toRead = (left >= sizeof(buf)) ? sizeof(buf):left;
134  /*
135  if (toRead > INT_MAX) {
136  toRead = INT_MAX;
137  }
138  */
139  if (fp->read(buf, toRead, fp) == toRead) {
140  hmac_update(ctx,(uint8 *)&buf,toRead);
141  left -= toRead;
142  } else {
143  ret = false;
144  break;
145  }
146  }
147 
148  size_t size = ctx->hashSize;
149  unsigned char * hashtmp = (unsigned char *)dsl_malloc(ctx->hashSize);
150  bool ret2 = hmac_finish(ctx, hashtmp, size);
151  if (ret2) {
152  ret2 = (bin2hex(hashtmp, size, out, outlen) != NULL);
153  }
154  dsl_free(hashtmp);
155  return (ret && ret2);
156 }
DSL_API void DSL_CC dsl_free(void *ptr)
Definition: dsl.cpp:345
DSL_API_CLASS char *DSL_CC bin2hex(const uint8_t *data, size_t datalen, char *out, size_t outsize)
Definition: GenLib.cpp:129
DSL_API bool DSL_CC hmacfile_rw(const char *name, const uint8 *key, size_t keylen, DSL_FILE *fp, char *out, size_t outlen)
Wrapper around hmac_init()/hmac_update()/hmac_finish(). If raw_output == true out will contain binary...
Definition: hmac.cpp:116
DSL_API bool DSL_CC hmacfile(const char *name, const uint8 *key, size_t keylen, const char *fn, char *out, size_t outlen)
Wrapper around hmac_init()/hmac_update()/hmac_finish(). If raw_output == true out will contain binary...
Definition: hmac.cpp:94
bool DSL_CC hmac_finish(HASH_HMAC_CTX *ctx, uint8 *out, size_t outlen)
Finalize HMAC and store in out. outlen should be >= hashSize in the HASH_CTX struct....
Definition: hmac.cpp:66
HASH_HMAC_CTX *DSL_CC hmac_init(const char *name, const uint8 *key, size_t length)
Definition: hmac.cpp:47
DSL_API bool DSL_CC hmacdata(const char *name, const uint8 *key, size_t keylen, const uint8 *data, size_t datalen, char *out, size_t outlen)
Wrapper around hmac_init()/hmac_update()/hmac_finish(). If raw_output == true out will contain binary...
Definition: hmac.cpp:73
DSL_API bool DSL_CC hmacfile_fp(const char *name, const uint8 *key, size_t keylen, FILE *fpp, char *out, size_t outlen)
Wrapper around hmac_init()/hmac_update()/hmac_finish(). If raw_output == true out will contain binary...
Definition: hmac.cpp:104
void DSL_CC hmac_update(HASH_HMAC_CTX *ctx, const uint8 *data, size_t len)
Call with the data you want to hash, can be called multiple times to hash a large file in chunks for ...
Definition: hmac.cpp:59
DSL_API DSL_FILE *DSL_CC RW_ConvertFile(FILE *fp, bool autoclose)
Definition: rwops.cpp:68
DSL_API DSL_FILE *DSL_CC RW_OpenFile(const char *fn, const char *mode)
Definition: rwops.cpp:50
Definition: rwops.h:24
void(* close)(DSL_FILE *fp)
Definition: rwops.h:54
bool(* seek)(DSL_FILE *fp, int64 pos, int mode)
Definition: rwops.h:31
int64(* read)(void *buf, int64 size, DSL_FILE *fp)
Definition: rwops.h:36
int64(* tell)(DSL_FILE *fp)
Definition: rwops.h:45