ykey.c
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * $Id: ykey.c 24249 2016-04-26 13:03:58Z seb $
4  *
5  * Implementation of standard key computations
6  *
7  * - - - - - - - - - License information: - - - - - - - - -
8  *
9  * Copyright (C) 2011 and beyond by Yoctopuce Sarl, Switzerland.
10  *
11  * Yoctopuce Sarl (hereafter Licensor) grants to you a perpetual
12  * non-exclusive license to use, modify, copy and integrate this
13  * file into your software for the sole purpose of interfacing
14  * with Yoctopuce products.
15  *
16  * You may reproduce and distribute copies of this file in
17  * source or object form, as long as the sole purpose of this
18  * code is to interface with Yoctopuce products. You must retain
19  * this notice in the distributed source file.
20  *
21  * You should refer to Yoctopuce General Terms and Conditions
22  * for additional information regarding your rights and
23  * obligations.
24  *
25  * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
26  * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
27  * WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS
28  * FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO
29  * EVENT SHALL LICENSOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
30  * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
31  * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR
32  * SERVICES, ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT
33  * LIMITED TO ANY DEFENSE THEREOF), ANY CLAIMS FOR INDEMNITY OR
34  * CONTRIBUTION, OR OTHER SIMILAR COSTS, WHETHER ASSERTED ON THE
35  * BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF
36  * WARRANTY, OR OTHERWISE.
37  *
38  *********************************************************************/
39 #define __FILE_ID__ "ydef"
40 #include "ykey.h"
41 
42 #ifdef MICROCHIP_API
43 #include "Yocto/yocto.h"
44 #include "Yocto/yapi_ext.h"
45 #define ntohl(dw) swapl(dw)
46 #else
47 #include <string.h>
48 #include "yproto.h"
49 #endif
50 
51 static char btohexa_low_high(u8 b)
52 {
53  b >>= 4;
54  return (b>9u) ? b+'a'-10 : b+'0';
55 }
56 
57 static char btohexa_low_low(u8 b)
58 {
59  b &= 0x0F;
60  return (b>9u) ? b+'a'-10 : b+'0';
61 }
62 
63 void bin2str(char *to, const u8 *p, u16 len, u8 addnull)
64 {
65  for (; len--; p++) {
66  *to++ = btohexa_low_high(*p);
67  *to++ = btohexa_low_low(*p);
68  }
69  if(addnull) *to = '\0';
70 }
71 
72 #if !defined(MICROCHIP_API) || defined(HTTP_ON_NET)
73 
74 //#define DEBUG_HTTP_AUTHENTICATION
75 
76 // compute the ha1 (in binary form)
77 void ComputeAuthHA1(u8 *ha1, const char *user, const char *pass, const char *realm)
78 {
79  HASH_SUM ctx;
80 
81  MD5Initialize(&ctx);
82  MD5AddData(&ctx, (u8*)user, YSTRLEN(user));
83  MD5AddData(&ctx, (u8*)":", 1);
84  MD5AddData(&ctx, (u8*)realm, YSTRLEN(realm));
85  MD5AddData(&ctx, (u8*)":", 1);
86  MD5AddData(&ctx, (u8*)pass, YSTRLEN(pass));
87  MD5Calculate(&ctx, ha1);
88 #ifdef DEBUG_HTTP_AUTHENTICATION
89  {
90  char tmpha[HTTP_AUTH_MD5_STRLEN + 1];
91  bin2str(tmpha, ha1, HTTP_AUTH_MD5_SIZE, 1);
92  dbglog("Compute HA1 u=%s r=%s p=%s -> %s\n", user, realm, pass, tmpha);
93  }
94 #endif
95 }
96 
97 // compute the ha2 (in binary form)
98 void ComputeAuthHA2(u8 *ha2, const char *method, const char *uri)
99 {
100  HASH_SUM ctx;
101 
102  MD5Initialize(&ctx);
103  MD5AddData(&ctx, (u8*)method, YSTRLEN(method));
104  MD5AddData(&ctx, (u8*)":", 1);
105  MD5AddData(&ctx, (u8*)uri, YSTRLEN(uri));
106  MD5Calculate(&ctx, ha2);
107 #ifdef DEBUG_HTTP_AUTHENTICATION
108  {
109  char tmpha[HTTP_AUTH_MD5_STRLEN + 1];
110  bin2str(tmpha, ha2, HTTP_AUTH_MD5_SIZE, 1);
111  dbglog("Compute HA2 m=%s u=%s -> %s\n", method, uri, tmpha);
112  }
113 #endif
114 }
115 
116 
117 // Return stringified MD5 hash for the specified parameters
118 void ComputeAuthResponse(char *buf, const u8 *ha1, const char *nonce, const char *nc, const char *cnonce, const u8* ha2)
119 {
120  u8 hash[HTTP_AUTH_MD5_SIZE];
121  char tmpha[HTTP_AUTH_MD5_STRLEN+1];
122  HASH_SUM ctx;
123 
124  MD5Initialize(&ctx);
125  // convert ha1 into str before using it
126  bin2str(tmpha, ha1, HTTP_AUTH_MD5_SIZE,1);
127  MD5AddData(&ctx, (u8*)tmpha, HTTP_AUTH_MD5_STRLEN);
128  MD5AddData(&ctx, (u8*)":", 1);
129  MD5AddData(&ctx, (u8*)nonce, YSTRLEN(nonce));
130  MD5AddData(&ctx, (u8*)":", 1);
131  if(nc && cnonce) {
132  MD5AddData(&ctx, (u8*)nc, YSTRLEN(nc));
133  MD5AddData(&ctx, (u8*)":", 1);
134  MD5AddData(&ctx, (u8*)cnonce, YSTRLEN(cnonce));
135  MD5AddData(&ctx, (u8*)":auth:", 6);
136  }
137  bin2str(tmpha, ha2, HTTP_AUTH_MD5_SIZE,1);
138  MD5AddData(&ctx, (u8*)tmpha, HTTP_AUTH_MD5_STRLEN);
139  MD5Calculate(&ctx,hash);
140  bin2str(buf, hash, HTTP_AUTH_MD5_SIZE,1);
141 #ifdef DEBUG_HTTP_AUTHENTICATION
142  {
143  char tmpha1[HTTP_AUTH_MD5_STRLEN + 1];
144  bin2str(tmpha1, ha1, HTTP_AUTH_MD5_SIZE, 1);
145  if (nc && cnonce) {
146  dbglog("Auth Resp ha1=%s nonce=%s nc=%s cnouce=%s ha2=%s -> %s\n",
147  tmpha1, nonce, nc, cnonce, tmpha, buf);
148  } else {
149  dbglog("Auth Resp ha1=%s nonce=%s (no nc/cnounce) ha2=%s -> %s\n",
150  tmpha1, nonce, tmpha, buf);
151  }
152  }
153 #endif
154 }
155 
156 
157 // Return stringified sha1 hash for the specified parameters
158 int CheckWSAuth(u32 nonce, const u8 *ha1, const u8 *to_verify, u8 *out)
159 {
160  char tmpbuff[HTTP_AUTH_MD5_STRLEN + 8 + 1];
161  const u8 * sha1;
162  int res;
163 
164  // convert ha1 into str before using it
165  bin2str(tmpbuff, ha1, HTTP_AUTH_MD5_SIZE, 1);
166 #ifdef DEBUG_HTTP_AUTHENTICATION
167  dbglog("ha1=%s\n", tmpbuff);
168 #endif
169  // convert ha1 into str before using it
170 #ifdef CPU_BIG_ENDIAN
171  nonce = INTEL_U32(nonce);
172 #endif
173  bin2str(tmpbuff + HTTP_AUTH_MD5_STRLEN, (u8*) &nonce, 4, 1);
174 #ifdef DEBUG_HTTP_AUTHENTICATION
175  dbglog("full=%s\n", tmpbuff);
176 #endif
177  sha1 = ySHA1(tmpbuff);
178  if (out) {
179  memcpy(out, sha1, 20);
180  }
181  if (to_verify == NULL) {
182  return 0;
183  }
184  res = memcmp(sha1, to_verify, 20)==0;
185  return res;
186 }
187 
188 // Parse a request header, return 0 if a valid WWW-Authenticate header and set args to corresponding fields
189 // - Request is patched in place to null-terminate each field.
190 // - If return value is 0, at least method,realm and qop are set to non-NULL value
191 // - qop is set to an empty string if not specified in thq authenticate header
192 int yParseWWWAuthenticate(char *replybuf, int replysize, char **method, char **realm, char **qop, char **nonce, char **opaque)
193 {
194  int pos = 0;
195  char *p=replybuf, *start;
196 
197  while(pos < replysize) {
198  while(pos < replysize && replybuf[pos] != '\r') pos++;
199  if(pos < replysize && replybuf[++pos] == '\n') pos++;
200  // new line, look for authorization header (always at least 25 chars)
201  if(pos+25 >= replysize) return -1;
202  if(YSTRNICMP(replybuf+pos, "WWW-Authenticate:", 17) != 0) continue;
203  // header found, keep a pointer to content and make sure it is complete
204  pos += 17;
205  p = replybuf + pos;
206  while(pos < replysize && replybuf[pos] != '\r') pos++;
207  break;
208  }
209  if(pos >= replysize) return -1;
210  replybuf[pos] = 0;
211  // we now have a full null-terminated authentication header to parse at p
212  while(*p == ' ') p++;
213  start = p;
214  while(*p && *p != ' ') p++;
215  // we expect at least a realm after the method name
216  if(!*p) return -1;
217  // method found, followed by something. Set default realm and qop to an empty string
218  *method = start;
219  *realm = replybuf+pos;
220  *qop = replybuf+pos;
221  // null-terminate the method name, and proceed to named parameters
222  *p++ = 0;
223  while(*p) {
224  while(*p == ' ' || *p == ',') p++;
225  if(!*p) break;
226  if(YSTRNICMP(p,"realm=\"",7) == 0) {
227  p += 7;
228  start = p;
229  while(*p && *p != '\"') p++;
230  if(!*p) return -1;
231  *p++ = 0; // replace quote by NUL
232  *realm = start;
233  } else if(YSTRNICMP(p,"qop=\"",5) == 0) {
234  p += 5;
235  start = p;
236  while(*p && *p != '\"') p++;
237  if(!*p) return -1;
238  *p++ = 0; // replace quote by NUL
239  *qop = start;
240  } else if(YSTRNICMP(p,"nonce=\"",7) == 0) {
241  p += 7;
242  start = p;
243  while(*p && *p != '\"') p++;
244  if(!*p) return -1;
245  *p++ = 0; // replace quote by NUL
246  *nonce = start;
247  } else if(YSTRNICMP(p,"opaque=\"",8) == 0) {
248  p += 8;
249  start = p;
250  while(*p && *p != '\"') p++;
251  if(!*p) return -1;
252  *p++ = 0; // replace quote by NUL
253  *opaque = start;
254  } else {
255  // skip unknown tag
256  while(*p && *p != ',') p++;
257  }
258  }
259  // if no non-empty realm has been specified, the authentication header is not valid
260  if(!**realm) return -1;
261 
262  return 0;
263 }
264 
265 extern u32 yapiGetCNonce(u32 nc);
266 
267 // Write an authorization header in the buffer provided
268 // method and uri can be provided in the same memory zone as destination if needed
269 void yDigestAuthorization(char *buf, int bufsize, const char *user, const char *realm, const u8 *ha1,
270  const char *nonce, const char *opaque, u32 *nc, const char *method, const char *uri)
271 {
272  u32 cnonce;
273  char ncbuf[9], cnoncebuf[9];
274  u8 ha2[HTTP_AUTH_MD5_SIZE];
275  int len;
276 
277  ComputeAuthHA2(ha2, method, uri);
278  YSTRCPY(buf, bufsize, "Authorization: Digest username=\"");
279  YSTRCAT(buf, bufsize, user);
280  YSTRCAT(buf, bufsize, "\", realm=\"");
281  YSTRCAT(buf, bufsize, realm);
282  YSTRCAT(buf, bufsize, "\", nonce=\"");
283  YSTRCAT(buf, bufsize, nonce);
284  YSTRCAT(buf, bufsize, "\", uri=\"");
285  YSTRCAT(buf, bufsize, uri);
286  if(nc) {
287  (*nc)++;
288  cnonce = yapiGetCNonce(*nc);
289  yxtoa(*nc, ncbuf, sizeof(ncbuf)-1);
290  yxtoa(cnonce, cnoncebuf, sizeof(cnoncebuf)-1);
291  len = (int)strlen(buf);
292  buf += len;
293  bufsize -= len;
294  YSTRCAT(buf, bufsize, "\", qop=auth, nc=");
295  YSTRCAT(buf, bufsize, ncbuf);
296  YSTRCAT(buf, bufsize, ", cnonce=\"");
297  YSTRCAT(buf, bufsize, cnoncebuf);
298  }
299  YSTRCAT(buf, bufsize, "\", response=\"");
300  len = (int)strlen(buf);
301  buf += len;
302  bufsize -= len;
303  ComputeAuthResponse(buf, ha1, nonce, (nc?ncbuf:NULL), (nc?cnoncebuf:NULL), ha2);
304  if(opaque) {
305  len = (int)strlen(buf);
306  buf += len;
307  bufsize -= len;
308  YSTRCAT(buf, bufsize, "\", opaque=\"");
309  YSTRCAT(buf, bufsize, opaque);
310  }
311  YSTRCAT(buf, bufsize, "\"\r\n");
312 }
313 
314 // State variables used during key computation
315 typedef struct {
316  int iter;
317  int pos;
318  u32 inner[5];
319  u32 outer[5];
320  u32 shau[5];
321  u32 shaw[80];
322  u8 res[32];
324 
325 static WPA_CALC_STATE wpak = { -1 };
326 
327 const u32 sha1_init[5] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };
328 
329 static void initshaw(const char *s, u16 ofs, u8 pad, u16 xinit)
330 {
331  int ii, j = -1, k = 0;
332  int n = (int)strlen(s);
333 
334  for(ii = 0; ii < 64; ii++) {
335  int i = ofs + ii;
336  u8 c = 0;
337  if (i < n) {
338  c = s[i];
339  } else if (pad) {
340  if (pad & 0x80) {
341  if (i == n) c = pad;
342  } else {
343  if (i == n + 3) c = pad;
344  else if (i == n + 4) c = 0x80;
345  }
346  }
347  if (k == 0) {
348  j++;
349  wpak.shaw[j] = 0;
350  k = 32;
351  }
352  k -= 8;
353  wpak.shaw[j] |= ((u32)c << k);
354  }
355  if(pad) {
356  if(pad == 0x80) {
357  if(n <= ofs+55) {
358  wpak.shaw[15] = 8 * n;
359  }
360  } else {
361  wpak.shaw[15] = 8 * (n + 68);
362  }
363  }
364  if(xinit) {
365  u32 xdw = ((u32)xinit << 16) | xinit;
366  for (j = 0; j < 16; j++) {
367  wpak.shaw[j] ^= xdw;
368  }
369  }
370 }
371 
372 static void itershaw(const u32 *s)
373 {
374  u32 a, b, c, d, e, t;
375  int k;
376 
377  a = s[0];
378  b = s[1];
379  c = s[2];
380  d = s[3];
381  e = s[4];
382  for (k = 16; k < 80; k++) {
383  t = wpak.shaw[k - 3] ^ wpak.shaw[k - 8] ^ wpak.shaw[k - 14] ^ wpak.shaw[k - 16];
384  wpak.shaw[k] = (t << 1) | (t >> 31);
385  }
386  for (k = 0; k < 20; k++) {
387  t = ((a << 5) | (a >> 27)) + e + wpak.shaw[k] + 0x5A827999 + ((b & c) | ((~b) & d));
388  e = d;
389  d = c;
390  c = (b << 30) | (b >> 2);
391  b = a;
392  a = t;
393  }
394  for (k = 20; k < 40; k++) {
395  t = ((a << 5) | (a >> 27)) + e + wpak.shaw[k] + 0x6ED9EBA1 + (b^c^d);
396  e = d;
397  d = c;
398  c = (b << 30) | (b >> 2);
399  b = a;
400  a = t;
401  }
402  for (k = 40; k < 60; k++) {
403  t = ((a << 5) | (a >> 27)) + e + wpak.shaw[k] + 0x8F1BBCDC + ((b & c) | (b & d) | (c & d));
404  e = d;
405  d = c;
406  c = (b << 30) | (b >> 2);
407  b = a;
408  a = t;
409  }
410  for (k = 60; k < 80; k++) {
411  t = ((a << 5) | (a >> 27)) + e + wpak.shaw[k] + 0xCA62C1D6 + (b^c^d);
412  e = d;
413  d = c;
414  c = (b << 30) | (b >> 2);
415  b = a;
416  a = t;
417  }
418  wpak.shaw[0] = s[0] + a;
419  wpak.shaw[1] = s[1] + b;
420  wpak.shaw[2] = s[2] + c;
421  wpak.shaw[3] = s[3] + d;
422  wpak.shaw[4] = s[4] + e;
423 }
424 
425 u8 *ySHA1(const char *text)
426 {
427  int ofs = 0, n = (int)strlen(text);
428 
429  memcpy((u8 *)wpak.shau, (u8 *)sha1_init, sizeof(wpak.shau));
430  do {
431  initshaw(text, ofs, 0x80, 0);
432  itershaw(wpak.shau);
433  memcpy((u8 *)wpak.shau, (u8 *)wpak.shaw, sizeof(wpak.shau));
434  ofs += 64;
435  } while(n > ofs-9);
436 #ifndef CPU_BIG_ENDIAN
437  for(ofs = 0; ofs < 5; ofs++) {
438  wpak.shau[ofs] = ntohl(wpak.shau[ofs]);
439  }
440 #endif
441 
442  return (u8 *)wpak.shau;
443 }
444 
445 void yInitPsk(const char *pass, const char *ssid)
446 {
447  // precompute part of sha used in the loops
448  initshaw(pass, 0, 0, 0x3636);
450  memcpy(wpak.inner, wpak.shaw, sizeof(wpak.inner));
451 
452  initshaw(pass, 0, 0, 0x5c5c);
454  memcpy(wpak.outer, wpak.shaw, sizeof(wpak.outer));
455 
456  // prepare to compute first 20 bytes
457  wpak.pos = 0;
458  wpak.iter = 0;
459  memset(wpak.shau, 0, sizeof(wpak.shau));
460  initshaw(ssid, 0, 1, 0);
461 }
462 
463 int yIterPsk(u8 *res, const char *ssid)
464 {
465  int k;
466 
467  if(wpak.iter < 0) return -1;
468  if(wpak.iter >= 8192) return 0;
469  itershaw(wpak.inner);
470  wpak.shaw[5] = 0x80000000;
471  for (k = 6; k < 15; k++) {
472  wpak.shaw[k] = 0;
473  }
474  wpak.shaw[15] = 8 * (64 + 20);
475  itershaw(wpak.outer);
476  wpak.shau[0] ^= wpak.shaw[0];
477  wpak.shau[1] ^= wpak.shaw[1];
478  wpak.shau[2] ^= wpak.shaw[2];
479  wpak.shau[3] ^= wpak.shaw[3];
480  wpak.shau[4] ^= wpak.shaw[4];
481  wpak.iter++;
482  // after 4096 loops, move to 2nd half of sha1
483  if((wpak.iter & 4095) == 0) {
484  for(k = 0; k < 5 && wpak.pos < 32; k++) {
485  wpak.res[wpak.pos++] = (wpak.shau[k] >> 24) & 0xff;
486  wpak.res[wpak.pos++] = (wpak.shau[k] >> 16) & 0xff;
487  wpak.res[wpak.pos++] = (wpak.shau[k] >> 8) & 0xff;
488  wpak.res[wpak.pos++] = wpak.shau[k] & 0xff;
489  }
490  if(wpak.iter == 4096) {
491  memset(wpak.shau, 0, sizeof(wpak.shau));
492  initshaw(ssid, 0,2, 0);
493  } else {
494  // done
495  memcpy(res, wpak.res, 32);
496  return 0;
497  }
498  }
499  // return 1 to ask for more loops
500  return 1;
501 }
502 
503 #endif
504 
505 #ifndef MICROCHIP_API
506 /*
507  * MD5 implementation below is mostly from Sergey Lyubka, author of SHTTPD.
508  * Any other implementation would do as well, but we like this one.
509  * This code has been published by Sergey under his "THE BEER-WARE LICENSE" (Revision 42):
510  *
511  * Sergey Lyubka wrote this software. As long as you retain this notice you
512  * can do whatever you want with this stuff. If we meet some day, and you think
513  * this stuff is worth it, you can buy me a beer in return.
514  */
515 
516 #ifndef CPU_BIG_ENDIAN
517 #define byteReverse(buf, len) // Do nothing
518 #else
519 static void byteReverse(unsigned char *buf, unsigned longs) {
520  u32 t;
521  do {
522  t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
523  ((unsigned) buf[1] << 8 | buf[0]);
524  *(u32 *) buf = t;
525  buf += 4;
526  } while (--longs);
527 }
528 #endif
529 
530 #define F1(x, y, z) (z ^ (x & (y ^ z)))
531 #define F2(x, y, z) F1(z, x, y)
532 #define F3(x, y, z) (x ^ y ^ z)
533 #define F4(x, y, z) (y ^ (x | ~z))
534 
535 #define MD5STEP(f, w, x, y, z, data, s) \
536 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
537 
538 // Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
539 // initialization constants.
541 {
542  ctx->buf[0] = 0x67452301;
543  ctx->buf[1] = 0xefcdab89;
544  ctx->buf[2] = 0x98badcfe;
545  ctx->buf[3] = 0x10325476;
546 
547  ctx->bits[0] = 0;
548  ctx->bits[1] = 0;
549 }
550 
551 static void MD5Transform(u32 buf[4], u32 const in[16])
552 {
553  register u32 a, b, c, d;
554 
555  a = buf[0];
556  b = buf[1];
557  c = buf[2];
558  d = buf[3];
559 
560  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
561  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
562  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
563  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
564  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
565  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
566  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
567  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
568  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
569  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
570  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
571  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
572  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
573  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
574  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
575  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
576 
577  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
578  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
579  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
580  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
581  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
582  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
583  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
584  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
585  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
586  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
587  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
588  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
589  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
590  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
591  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
592  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
593 
594  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
595  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
596  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
597  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
598  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
599  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
600  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
601  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
602  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
603  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
604  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
605  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
606  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
607  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
608  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
609  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
610 
611  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
612  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
613  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
614  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
615  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
616  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
617  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
618  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
619  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
620  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
621  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
622  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
623  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
624  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
625  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
626  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
627 
628  buf[0] += a;
629  buf[1] += b;
630  buf[2] += c;
631  buf[3] += d;
632 }
633 
634 void MD5AddData(HASH_SUM *ctx, const u8 *buf, u32 len)
635 {
636  u32 t;
637 
638  t = ctx->bits[0];
639  if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
640  ctx->bits[1]++;
641  ctx->bits[1] += len >> 29;
642 
643  t = (t >> 3) & 0x3f;
644 
645  if (t) {
646  unsigned char *p = (unsigned char *) ctx->in + t;
647 
648  t = 64 - t;
649  if (len < t) {
650  memcpy(p, buf, len);
651  return;
652  }
653  memcpy(p, buf, t);
654  byteReverse(ctx->in, 16);
655  MD5Transform(ctx->buf, (u32 *) ctx->in);
656  buf += t;
657  len -= t;
658  }
659 
660  while (len >= 64) {
661  memcpy(ctx->in, buf, 64);
662  byteReverse(ctx->in, 16);
663  MD5Transform(ctx->buf, (u32 *) ctx->in);
664  buf += 64;
665  len -= 64;
666  }
667 
668  memcpy(ctx->in, buf, len);
669 }
670 
671 void MD5Calculate(HASH_SUM *ctx, u8 digest[16])
672 {
673  unsigned count;
674  unsigned char *p;
675 
676  count = (ctx->bits[0] >> 3) & 0x3F;
677 
678  p = ctx->in + count;
679  *p++ = 0x80;
680  count = 64 - 1 - count;
681  if (count < 8) {
682  memset(p, 0, count);
683  byteReverse(ctx->in, 16);
684  MD5Transform(ctx->buf, (u32 *) ctx->in);
685  memset(ctx->in, 0, 56);
686  } else {
687  memset(p, 0, count - 8);
688  }
689  byteReverse(ctx->in, 14);
690 
691  ctx->in32[14] = ctx->bits[0];
692  ctx->in32[15] = ctx->bits[1];
693 
694  MD5Transform(ctx->buf, (u32 *) ctx->in);
695  byteReverse((unsigned char *) ctx->buf, 4);
696  memcpy(digest, ctx->buf, 16);
697  memset((char *) ctx, 0, sizeof(*ctx));
698 }
699 #endif
700 
d
ROSCPP_DECL void start()
Definition: ykey.h:74
static WPA_CALC_STATE wpak
Definition: ykey.c:325
void ComputeAuthHA2(u8 *ha2, const char *method, const char *uri)
Definition: ykey.c:98
u32 shaw[80]
Definition: ykey.c:321
#define F1(x, y, z)
Definition: ykey.c:530
#define YSTRCAT(dst, dstsize, src)
Definition: yproto.h:235
u32 bits[2]
Definition: ykey.h:76
u8 * ySHA1(const char *text)
Definition: ykey.c:425
#define dbglog(args...)
Definition: yproto.h:413
static char btohexa_low_high(u8 b)
Definition: ykey.c:51
u32 inner[5]
Definition: ykey.c:318
int yIterPsk(u8 *res, const char *ssid)
Definition: ykey.c:463
#define INTEL_U32(NUM)
Definition: ydef.h:982
#define YSTRNICMP(A, B, len)
Definition: yproto.h:229
static void MD5Transform(u32 buf[4], u32 const in[16])
Definition: ykey.c:551
#define F4(x, y, z)
Definition: ykey.c:533
u32 shau[5]
Definition: ykey.c:320
void bin2str(char *to, const u8 *p, u16 len, u8 addnull)
Definition: ykey.c:63
void MD5Calculate(HASH_SUM *ctx, u8 digest[16])
Definition: ykey.c:671
static void initshaw(const char *s, u16 ofs, u8 pad, u16 xinit)
Definition: ykey.c:329
#define YSTRCPY(dst, dstsize, src)
Definition: yproto.h:234
#define HTTP_AUTH_MD5_STRLEN
Definition: ykey.h:49
#define MD5STEP(f, w, x, y, z, data, s)
Definition: ykey.c:535
void yDigestAuthorization(char *buf, int bufsize, const char *user, const char *realm, const u8 *ha1, const char *nonce, const char *opaque, u32 *nc, const char *method, const char *uri)
Definition: ykey.c:269
static char btohexa_low_low(u8 b)
Definition: ykey.c:57
int CheckWSAuth(u32 nonce, const u8 *ha1, const u8 *to_verify, u8 *out)
Definition: ykey.c:158
#define YSTRLEN(str)
Definition: yproto.h:230
u32 outer[5]
Definition: ykey.c:319
void ComputeAuthHA1(u8 *ha1, const char *user, const char *pass, const char *realm)
Definition: ykey.c:77
void MD5Initialize(HASH_SUM *ctx)
Definition: ykey.c:540
void yxtoa(u32 x, char *buf, u16 len)
Definition: yfifo.c:413
u32 buf[4]
Definition: ykey.h:75
#define F3(x, y, z)
Definition: ykey.c:532
#define F2(x, y, z)
Definition: ykey.c:531
#define byteReverse(buf, len)
Definition: ykey.c:517
int yParseWWWAuthenticate(char *replybuf, int replysize, char **method, char **realm, char **qop, char **nonce, char **opaque)
Definition: ykey.c:192
u8 res[32]
Definition: ykey.c:322
const u32 sha1_init[5]
Definition: ykey.c:327
u32 in32[16]
Definition: ykey.h:79
int iter
Definition: ykey.c:316
static void itershaw(const u32 *s)
Definition: ykey.c:372
void yInitPsk(const char *pass, const char *ssid)
Definition: ykey.c:445
void ComputeAuthResponse(char *buf, const u8 *ha1, const char *nonce, const char *nc, const char *cnonce, const u8 *ha2)
Definition: ykey.c:118
u8 in[64]
Definition: ykey.h:78
u32 yapiGetCNonce(u32 nc)
Definition: yapi.c:2750
void MD5AddData(HASH_SUM *ctx, const u8 *buf, u32 len)
Definition: ykey.c:634
#define HTTP_AUTH_MD5_SIZE
Definition: ykey.h:48


yoctopuce_altimeter
Author(s): Anja Sheppard
autogenerated on Mon Jun 10 2019 15:49:10