gwenhywfar  4.8.0beta
cryptdefs.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id: crypttoken.h 1113 2007-01-10 09:14:16Z martin $
5  begin : Wed Mar 16 2005
6  copyright : (C) 2005 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * Please see toplevel file COPYING for license details *
11  ***************************************************************************/
12 
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
16 
17 
18 #include "cryptdefs_p.h"
19 #include <gwenhywfar/misc.h>
20 #include <gwenhywfar/debug.h>
21 
22 #include <gwenhywfar/mdigest.h>
23 
24 #include <gcrypt.h>
25 
26 
27 
28 
30  assert(s);
31  if (strcasecmp(s, "none")==0)
33  else if (strcasecmp(s, "access")==0)
35  else if (strcasecmp(s, "manage")==0)
38 }
39 
40 
41 
43  switch(pt) {
45  return "none";
47  return "access";
49  return "manage";
50  default:
51  return "unknown";
52  }
53 }
54 
55 
56 
58  assert(s);
59  if (strcasecmp(s, "none")==0)
61  else if (strcasecmp(s, "bin")==0)
63  else if (strcasecmp(s, "bcd")==0)
65  else if (strcasecmp(s, "ascii")==0)
67  else if (strcasecmp(s, "fpin2")==0)
70 }
71 
72 
73 
75  switch(pe) {
77  return "none";
79  return "bin";
81  return "bcd";
83  return "ascii";
85  return "fpin2";
86  default:
87  return "unknown";
88  }
89 }
90 
91 
92 
93 int GWEN_Crypt__TransformFromBCD(unsigned char *buffer,
94  unsigned int bufLength,
95  unsigned int *pinLength) {
96  unsigned char *newBuf;
97  unsigned char *p;
98  unsigned int newSize;
99  unsigned int i;
100  unsigned int cnt=0;
101 
102  if (*pinLength==0)
103  return 0;
104 
105  newSize=*pinLength*2;
106  newBuf=(unsigned char*)malloc(newSize);
107  p=newBuf;
108  for (i=0; i<*pinLength; i++) {
109  unsigned char c1;
110  unsigned char c2;
111 
112  c1=buffer[i];
113  /* 1st digit */
114  c2=(c1 & 0xf0)>>4;
115  if (c2==0x0f)
116  break;
117  *(p++)=c2+'0';
118  cnt++;
119  /* 2nd digit */
120  c2=(c1 & 0x0f);
121  if (c2==0x0f)
122  break;
123  *(p++)=c2+'0';
124  cnt++;
125  }
126 
127  if (cnt>bufLength) {
128  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
129  cnt, bufLength);
130  free(newBuf);
132  }
133 
134  memset(buffer, 0, bufLength);
135  memmove(buffer, newBuf, cnt);
136  *pinLength=cnt;
137  free(newBuf);
138  return 0;
139 }
140 
141 
142 
143 int GWEN_Crypt__TransformFromFPIN2(unsigned char *buffer,
144  unsigned int bufLength,
145  unsigned int *pinLength) {
146  unsigned char *newBuf;
147  unsigned char *p;
148  unsigned int newSize;
149  unsigned int i;
150  unsigned int cnt=0;
151  unsigned int len;
152 
153  if (*pinLength<8) {
154  DBG_ERROR(GWEN_LOGDOMAIN, "Pin too small to be a FPIN2 (%d<8)", *pinLength);
155  return GWEN_ERROR_INVALID;
156  }
157  len=(buffer[0] & 0x0f);
158  newSize=len*2;
159  newBuf=(unsigned char*)malloc(newSize);
160  p=newBuf;
161  for (i=1; i<8; i++) {
162  unsigned char c1;
163  unsigned char c2;
164 
165  if (cnt>=len)
166  break;
167 
168  c1=buffer[i];
169  /* 1st digit */
170  c2=(c1 & 0xf0)>>4;
171  if (c2==0x0f)
172  break;
173  *(p++)=c2+'0';
174  cnt++;
175  if (cnt>=len)
176  break;
177 
178  /* 2nd digit */
179  c2=(c1 & 0x0f);
180  if (c2==0x0f)
181  break;
182  *(p++)=c2+'0';
183  cnt++;
184  }
185 
186  if (cnt>bufLength) {
187  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
188  cnt, bufLength);
189  free(newBuf);
191  }
192 
193  memset(buffer, 0, bufLength);
194  memmove(buffer, newBuf, cnt);
195  *pinLength=cnt;
196  return 0;
197 }
198 
199 
200 
201 int GWEN_Crypt__TransformFromBin(unsigned char *buffer,
202  unsigned int bufLength,
203  unsigned int *pinLength) {
204  unsigned int i;
205  unsigned char *newBuf;
206  unsigned char *p;
207  unsigned int newSize;
208 
209  if (*pinLength==0)
210  return 0;
211 
212  newSize=*pinLength;
213  newBuf=(unsigned char*)malloc(newSize);
214  p=newBuf;
215 
216  for (i=0; i<*pinLength; i++) {
217  unsigned char c;
218 
219  c=buffer[i];
220  if (c>9) {
221  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a digit > 9)");
222  free(newBuf);
223  return GWEN_ERROR_INVALID;
224  }
225  *p=c+'0';
226  }
227  memset(buffer, 0, bufLength);
228  memmove(buffer, newBuf, *pinLength);
229  free(newBuf);
230 
231  return 0;
232 }
233 
234 
235 
236 int GWEN_Crypt__TransformToBCD(unsigned char *buffer,
237  unsigned int bufLength,
238  unsigned int *pinLength) {
239  unsigned char *newBuf;
240  unsigned char *p;
241  unsigned int newSize;
242  unsigned int i;
243  unsigned int cnt=0;
244 
245  newSize=*pinLength/2+1;
246  newBuf=(unsigned char*)malloc(newSize);
247  memset(newBuf, 0xff, newSize);
248  p=newBuf;
249  i=0;
250  while (i<*pinLength) {
251  unsigned char c1;
252  unsigned char c2;
253 
254  /* 1st digit */
255  c1=buffer[i];
256  if (c1<'0' || c1>'9') {
257  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
258  free(newBuf);
259  return GWEN_ERROR_INVALID;
260  }
261  c1-='0';
262  c1=c1<<4;
263  *p=c1+0x0f; /* don't incement yet */
264  cnt++; /* only increment once !! */
265  i++;
266  if (i>=*pinLength)
267  break;
268 
269  /* 2nd digit */
270  c2=buffer[i];
271  if (c2<'0' || c2>'9') {
272  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
273  free(newBuf);
274  return GWEN_ERROR_INVALID;
275  }
276  c2-='0';
277  c1|=(c2 & 0x0f);
278  *(p++)=c1;
279  i++;
280  }
281 
282  if (cnt>bufLength) {
283  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
284  cnt, bufLength);
285  free(newBuf);
287  }
288 
289  memset(buffer, 0, bufLength);
290  for (i=0; i<cnt; i++)
291  buffer[i]=newBuf[i];
292  *pinLength=cnt;
293  free(newBuf);
294  return 0;
295 }
296 
297 
298 
299 int GWEN_Crypt__TransformToFPIN2(unsigned char *buffer,
300  unsigned int bufLength,
301  unsigned int *pinLength) {
302  unsigned char *newBuf;
303  unsigned char *p;
304  unsigned int newSize;
305  unsigned int i;
306 
307  if (*pinLength>14) {
308  DBG_ERROR(GWEN_LOGDOMAIN, "Pin too long for FPIN2 (%d>14)",
309  *pinLength);
310  return GWEN_ERROR_INVALID;
311  }
312  if (8>bufLength) {
313  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (8>%d)",
314  bufLength);
316  }
317 
318  newSize=8;
319  newBuf=(unsigned char*)malloc(newSize);
320  memset(newBuf, 0xff, newSize);
321  p=newBuf;
322  *(p++)=0x20+*pinLength;
323  i=0;
324  while (i<*pinLength) {
325  unsigned char c1;
326  unsigned char c2;
327 
328  /* 1st digit */
329  c1=buffer[i];
330  if (c1<'0' || c1>'9') {
331  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
332  free(newBuf);
333  return GWEN_ERROR_INVALID;
334  }
335  c1-='0';
336  c1=c1<<4;
337  *p=c1+0x0f; /* don't incement yet */
338  i++;
339  if (i>=*pinLength)
340  break;
341 
342  /* 2nd digit */
343  c2=buffer[i];
344  if (c2<'0' || c2>'9') {
345  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
346  free(newBuf);
347  return GWEN_ERROR_INVALID;
348  }
349  c2-='0';
350  c1|=(c2 & 0x0f);
351  *(p++)=c1;
352  i++;
353  }
354 
355  memset(buffer, 0, bufLength);
356  for (i=0; i<8; i++)
357  buffer[i]=newBuf[i];
358  *pinLength=8;
359  free(newBuf);
360  return 0;
361 
362 }
363 
364 
365 
366 int GWEN_Crypt__TransformToBin(unsigned char *buffer,
367  unsigned int bufLength,
368  unsigned int *pinLength) {
369  unsigned int i;
370  unsigned char *newBuf;
371  unsigned char *p;
372  unsigned int newSize;
373 
374  if (*pinLength==0)
375  return 0;
376 
377  newSize=*pinLength;
378  newBuf=(unsigned char*)malloc(newSize);
379  p=newBuf;
380 
381  for (i=0; i<*pinLength; i++) {
382  unsigned char c;
383 
384  c=buffer[i];
385  if (c<'0' || c>'9') {
386  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
387  free(newBuf);
388  return GWEN_ERROR_INVALID;
389  }
390  *(p++)=c-'0';
391  }
392  memset(buffer, 0, bufLength);
393  memmove(buffer, newBuf, *pinLength);
394  free(newBuf);
395 
396  return 0;
397 }
398 
399 
400 
403  unsigned char *buffer,
404  unsigned int bufLength,
405  unsigned int *pinLength) {
406  int rv;
407 
408  if (peSrc==peDst)
409  return 0;
410 
411  switch(peSrc) {
413  rv=GWEN_Crypt__TransformFromBin(buffer, bufLength, pinLength);
414  break;
416  rv=GWEN_Crypt__TransformFromBCD(buffer, bufLength, pinLength);
417  break;
419  rv=0;
420  break;
422  rv=GWEN_Crypt__TransformFromFPIN2(buffer, bufLength, pinLength);
423  break;
424  default:
426  "Unhandled source encoding \"%s\"",
428  return GWEN_ERROR_INVALID;
429  }
430  if (rv) {
431  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
432  return rv;
433  }
434 
435  switch(peDst) {
437  rv=GWEN_Crypt__TransformToBin(buffer, bufLength, pinLength);
438  break;
440  rv=GWEN_Crypt__TransformToBCD(buffer, bufLength, pinLength);
441  break;
443  rv=0;
444  break;
446  rv=GWEN_Crypt__TransformToFPIN2(buffer, bufLength, pinLength);
447  break;
448  default:
450  "Unhandled destination encoding \"%s\"",
452  return GWEN_ERROR_INVALID;
453  }
454  if (rv) {
455  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
456  return rv;
457  }
458 
459  return 0;
460 }
461 
462 
463 
464 
465 static int GWEN_Crypt__KeyDataFromText(const char *text,
466  unsigned char *buffer,
467  unsigned int bufLength) {
468  GWEN_MDIGEST *md;
469  int rv;
470 
471  assert(text);
472  assert(buffer);
473  assert(bufLength);
474 
475  switch(bufLength) {
476  case 16: md=GWEN_MDigest_Md5_new(); break;
477  case 20: md=GWEN_MDigest_Rmd160_new(); break;
478  default:
479  DBG_ERROR(GWEN_LOGDOMAIN, "Bad size (%d)", bufLength);
480  return GWEN_ERROR_BAD_SIZE;
481  }
482 
483  rv=GWEN_MDigest_Begin(md);
484  if (rv) {
485  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
486  GWEN_MDigest_free(md);
487  return rv;
488  }
489 
490  rv=GWEN_MDigest_Update(md,
491  (const uint8_t*)text,
492  strlen(text));
493  if (rv) {
494  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
495  GWEN_MDigest_free(md);
496  return rv;
497  }
498 
499  rv=GWEN_MDigest_End(md);
500  if (rv) {
501  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
502  GWEN_MDigest_free(md);
503  return rv;
504  }
505 
506  /* get hash, copy it to given buffer */
507  memmove(buffer, GWEN_MDigest_GetDigestPtr(md), bufLength);
508 
509  /* cleanup, return */
510  GWEN_MDigest_free(md);
511  return 0;
512 }
513 
514 
515 
516 int GWEN_Crypt_KeyDataFromText(const char *text,
517  unsigned char *buffer,
518  unsigned int bufLength) {
519  if (bufLength==24) {
520  int rv;
521 
522  rv=GWEN_Crypt__KeyDataFromText(text, buffer, 16);
523  if (rv)
524  return rv;
525  memmove(buffer+16, buffer, 8);
526  return rv;
527  }
528  else
529  return GWEN_Crypt__KeyDataFromText(text, buffer, bufLength);
530 }
531 
532 
533 
534 void GWEN_Crypt_Random(int quality, uint8_t *buffer, uint32_t len) {
535  uint8_t *data;
536  enum gcry_random_level q;
537 
538  switch(quality) {
539  case 0: q=GCRY_WEAK_RANDOM; break;
540  case 1: q=GCRY_STRONG_RANDOM; break;
541  case 2:
542  default: q=GCRY_VERY_STRONG_RANDOM; break;
543  }
544 
545  data=gcry_random_bytes(len, q);
546  assert(data);
547  memmove(buffer, data, len);
548  memset(data, 0, len);
549  free(data);
550 }
551 
552 
553 
554 
555 
556