gwenhywfar 5.12.0
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{
31 assert(s);
32 if (strcasecmp(s, "none")==0)
34 else if (strcasecmp(s, "access")==0)
36 else if (strcasecmp(s, "manage")==0)
39}
40
41
42
44{
45 switch (pt) {
47 return "none";
49 return "access";
51 return "manage";
52 default:
53 return "unknown";
54 }
55}
56
57
58
60{
61 assert(s);
62 if (strcasecmp(s, "none")==0)
64 else if (strcasecmp(s, "bin")==0)
66 else if (strcasecmp(s, "bcd")==0)
68 else if (strcasecmp(s, "ascii")==0)
70 else if (strcasecmp(s, "fpin2")==0)
73}
74
75
76
78{
79 switch (pe) {
81 return "none";
83 return "bin";
85 return "bcd";
87 return "ascii";
89 return "fpin2";
90 default:
91 return "unknown";
92 }
93}
94
95
96
97int GWEN_Crypt__TransformFromBCD(unsigned char *buffer,
98 unsigned int bufLength,
99 unsigned int *pinLength)
100{
101 unsigned char *newBuf;
102 unsigned char *p;
103 unsigned int newSize;
104 unsigned int i;
105 unsigned int cnt=0;
106
107 if (*pinLength==0)
108 return 0;
109
110 newSize=*pinLength*2;
111 newBuf=(unsigned char *)malloc(newSize);
112 p=newBuf;
113 for (i=0; i<*pinLength; i++) {
114 unsigned char c1;
115 unsigned char c2;
116
117 c1=buffer[i];
118 /* 1st digit */
119 c2=(c1 & 0xf0)>>4;
120 if (c2==0x0f)
121 break;
122 *(p++)=c2+'0';
123 cnt++;
124 /* 2nd digit */
125 c2=(c1 & 0x0f);
126 if (c2==0x0f)
127 break;
128 *(p++)=c2+'0';
129 cnt++;
130 }
131
132 if (cnt>bufLength) {
133 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
134 cnt, bufLength);
135 free(newBuf);
137 }
138
139 memset(buffer, 0, bufLength);
140 memmove(buffer, newBuf, cnt);
141 *pinLength=cnt;
142 free(newBuf);
143 return 0;
144}
145
146
147
148int GWEN_Crypt__TransformFromFPIN2(unsigned char *buffer,
149 unsigned int bufLength,
150 unsigned int *pinLength)
151{
152 unsigned char *newBuf;
153 unsigned char *p;
154 unsigned int newSize;
155 unsigned int i;
156 unsigned int cnt=0;
157 unsigned int len;
158
159 if (*pinLength<8) {
160 DBG_ERROR(GWEN_LOGDOMAIN, "Pin too small to be a FPIN2 (%d<8)", *pinLength);
161 return GWEN_ERROR_INVALID;
162 }
163 len=(buffer[0] & 0x0f);
164 newSize=len*2;
165 newBuf=(unsigned char *)malloc(newSize);
166 p=newBuf;
167 for (i=1; i<8; i++) {
168 unsigned char c1;
169 unsigned char c2;
170
171 if (cnt>=len)
172 break;
173
174 c1=buffer[i];
175 /* 1st digit */
176 c2=(c1 & 0xf0)>>4;
177 if (c2==0x0f)
178 break;
179 *(p++)=c2+'0';
180 cnt++;
181 if (cnt>=len)
182 break;
183
184 /* 2nd digit */
185 c2=(c1 & 0x0f);
186 if (c2==0x0f)
187 break;
188 *(p++)=c2+'0';
189 cnt++;
190 }
191
192 if (cnt>bufLength) {
193 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
194 cnt, bufLength);
195 free(newBuf);
197 }
198
199 memset(buffer, 0, bufLength);
200 memmove(buffer, newBuf, cnt);
201 *pinLength=cnt;
202 return 0;
203}
204
205
206
207int GWEN_Crypt__TransformFromBin(unsigned char *buffer,
208 unsigned int bufLength,
209 unsigned int *pinLength)
210{
211 unsigned int i;
212 unsigned char *newBuf;
213 unsigned char *p;
214 unsigned int newSize;
215
216 if (*pinLength==0)
217 return 0;
218
219 newSize=*pinLength;
220 newBuf=(unsigned char *)malloc(newSize);
221 p=newBuf;
222
223 for (i=0; i<*pinLength; i++) {
224 unsigned char c;
225
226 c=buffer[i];
227 if (c>9) {
228 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a digit > 9)");
229 free(newBuf);
230 return GWEN_ERROR_INVALID;
231 }
232 *p=c+'0';
233 }
234 memset(buffer, 0, bufLength);
235 memmove(buffer, newBuf, *pinLength);
236 free(newBuf);
237
238 return 0;
239}
240
241
242
243int GWEN_Crypt__TransformToBCD(unsigned char *buffer,
244 unsigned int bufLength,
245 unsigned int *pinLength)
246{
247 unsigned char *newBuf;
248 unsigned char *p;
249 unsigned int newSize;
250 unsigned int i;
251 unsigned int cnt=0;
252
253 newSize=*pinLength/2+1;
254 newBuf=(unsigned char *)malloc(newSize);
255 memset(newBuf, 0xff, newSize);
256 p=newBuf;
257 i=0;
258 while (i<*pinLength) {
259 unsigned char c1;
260 unsigned char c2;
261
262 /* 1st digit */
263 c1=buffer[i];
264 if (c1<'0' || c1>'9') {
265 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
266 free(newBuf);
267 return GWEN_ERROR_INVALID;
268 }
269 c1-='0';
270 c1=c1<<4;
271 *p=c1+0x0f; /* don't incement yet */
272 cnt++; /* only increment once !! */
273 i++;
274 if (i>=*pinLength)
275 break;
276
277 /* 2nd digit */
278 c2=buffer[i];
279 if (c2<'0' || c2>'9') {
280 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
281 free(newBuf);
282 return GWEN_ERROR_INVALID;
283 }
284 c2-='0';
285 c1|=(c2 & 0x0f);
286 *(p++)=c1;
287 i++;
288 }
289
290 if (cnt>bufLength) {
291 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
292 cnt, bufLength);
293 free(newBuf);
295 }
296
297 memset(buffer, 0, bufLength);
298 for (i=0; i<cnt; i++)
299 buffer[i]=newBuf[i];
300 *pinLength=cnt;
301 free(newBuf);
302 return 0;
303}
304
305
306
307int GWEN_Crypt__TransformToFPIN2(unsigned char *buffer,
308 unsigned int bufLength,
309 unsigned int *pinLength)
310{
311 unsigned char *newBuf;
312 unsigned char *p;
313 unsigned int newSize;
314 unsigned int i;
315
316 if (*pinLength>14) {
317 DBG_ERROR(GWEN_LOGDOMAIN, "Pin too long for FPIN2 (%d>14)",
318 *pinLength);
319 return GWEN_ERROR_INVALID;
320 }
321 if (8>bufLength) {
322 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (8>%d)",
323 bufLength);
325 }
326
327 newSize=8;
328 newBuf=(unsigned char *)malloc(newSize);
329 memset(newBuf, 0xff, newSize);
330 p=newBuf;
331 *(p++)=0x20+*pinLength;
332 i=0;
333 while (i<*pinLength) {
334 unsigned char c1;
335 unsigned char c2;
336
337 /* 1st digit */
338 c1=buffer[i];
339 if (c1<'0' || c1>'9') {
340 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
341 free(newBuf);
342 return GWEN_ERROR_INVALID;
343 }
344 c1-='0';
345 c1=c1<<4;
346 *p=c1+0x0f; /* don't incement yet */
347 i++;
348 if (i>=*pinLength)
349 break;
350
351 /* 2nd digit */
352 c2=buffer[i];
353 if (c2<'0' || c2>'9') {
354 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
355 free(newBuf);
356 return GWEN_ERROR_INVALID;
357 }
358 c2-='0';
359 c1|=(c2 & 0x0f);
360 *(p++)=c1;
361 i++;
362 }
363
364 memset(buffer, 0, bufLength);
365 for (i=0; i<8; i++)
366 buffer[i]=newBuf[i];
367 *pinLength=8;
368 free(newBuf);
369 return 0;
370
371}
372
373
374
375int GWEN_Crypt__TransformToBin(unsigned char *buffer,
376 unsigned int bufLength,
377 unsigned int *pinLength)
378{
379 unsigned int i;
380 unsigned char *newBuf;
381 unsigned char *p;
382 unsigned int newSize;
383
384 if (*pinLength==0)
385 return 0;
386
387 newSize=*pinLength;
388 newBuf=(unsigned char *)malloc(newSize);
389 p=newBuf;
390
391 for (i=0; i<*pinLength; i++) {
392 unsigned char c;
393
394 c=buffer[i];
395 if (c<'0' || c>'9') {
396 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
397 free(newBuf);
398 return GWEN_ERROR_INVALID;
399 }
400 *(p++)=c-'0';
401 }
402 memset(buffer, 0, bufLength);
403 memmove(buffer, newBuf, *pinLength);
404 free(newBuf);
405
406 return 0;
407}
408
409
410
413 unsigned char *buffer,
414 unsigned int bufLength,
415 unsigned int *pinLength)
416{
417 int rv;
418
419 if (peSrc==peDst)
420 return 0;
421
422 switch (peSrc) {
424 rv=GWEN_Crypt__TransformFromBin(buffer, bufLength, pinLength);
425 break;
427 rv=GWEN_Crypt__TransformFromBCD(buffer, bufLength, pinLength);
428 break;
430 rv=0;
431 break;
433 rv=GWEN_Crypt__TransformFromFPIN2(buffer, bufLength, pinLength);
434 break;
435 default:
437 "Unhandled source encoding \"%s\"",
439 return GWEN_ERROR_INVALID;
440 }
441 if (rv) {
442 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
443 return rv;
444 }
445
446 switch (peDst) {
448 rv=GWEN_Crypt__TransformToBin(buffer, bufLength, pinLength);
449 break;
451 rv=GWEN_Crypt__TransformToBCD(buffer, bufLength, pinLength);
452 break;
454 rv=0;
455 break;
457 rv=GWEN_Crypt__TransformToFPIN2(buffer, bufLength, pinLength);
458 break;
459 default:
461 "Unhandled destination encoding \"%s\"",
463 return GWEN_ERROR_INVALID;
464 }
465 if (rv) {
466 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
467 return rv;
468 }
469
470 return 0;
471}
472
473
474
475
476static int GWEN_Crypt__KeyDataFromText(const char *text,
477 unsigned char *buffer,
478 unsigned int bufLength)
479{
480 GWEN_MDIGEST *md;
481 int rv;
482
483 assert(text);
484 assert(buffer);
485 assert(bufLength);
486
487 switch (bufLength) {
488 case 16:
490 break;
491 case 20:
493 break;
494 default:
495 DBG_ERROR(GWEN_LOGDOMAIN, "Bad size (%d)", bufLength);
496 return GWEN_ERROR_BAD_SIZE;
497 }
498
499 rv=GWEN_MDigest_Begin(md);
500 if (rv) {
501 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
503 return rv;
504 }
505
507 (const uint8_t *)text,
508 strlen(text));
509 if (rv) {
510 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
512 return rv;
513 }
514
515 rv=GWEN_MDigest_End(md);
516 if (rv) {
517 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
519 return rv;
520 }
521
522 /* get hash, copy it to given buffer */
523 memmove(buffer, GWEN_MDigest_GetDigestPtr(md), bufLength);
524
525 /* cleanup, return */
527 return 0;
528}
529
530
531
532int GWEN_Crypt_KeyDataFromText(const char *text,
533 unsigned char *buffer,
534 unsigned int bufLength)
535{
536 if (bufLength==24) {
537 int rv;
538
539 rv=GWEN_Crypt__KeyDataFromText(text, buffer, 16);
540 if (rv)
541 return rv;
542 memmove(buffer+16, buffer, 8);
543 return rv;
544 }
545 else
546 return GWEN_Crypt__KeyDataFromText(text, buffer, bufLength);
547}
548
549
550
551void GWEN_Crypt_Random(int quality, uint8_t *buffer, uint32_t len)
552{
553 enum gcry_random_level q;
554
555 switch (quality) {
556 case 0:
557 q=GCRY_WEAK_RANDOM;
558 break;
559 case 1:
560 q=GCRY_STRONG_RANDOM;
561 break;
562 case 2:
563 default:
564 q=GCRY_VERY_STRONG_RANDOM;
565 break;
566 }
567
568 gcry_randomize(buffer, len, q);
569}
570
571
572
573
574
575
const char * GWEN_Crypt_PinType_toString(GWEN_CRYPT_PINTYPE pt)
Definition cryptdefs.c:43
int GWEN_Crypt__TransformToBin(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition cryptdefs.c:375
GWEN_CRYPT_PINTYPE GWEN_Crypt_PinType_fromString(const char *s)
Definition cryptdefs.c:29
int GWEN_Crypt_TransformPin(GWEN_CRYPT_PINENCODING peSrc, GWEN_CRYPT_PINENCODING peDst, unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition cryptdefs.c:411
int GWEN_Crypt__TransformToFPIN2(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition cryptdefs.c:307
int GWEN_Crypt__TransformFromBCD(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition cryptdefs.c:97
int GWEN_Crypt__TransformFromFPIN2(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition cryptdefs.c:148
GWEN_CRYPT_PINENCODING GWEN_Crypt_PinEncoding_fromString(const char *s)
Definition cryptdefs.c:59
int GWEN_Crypt__TransformFromBin(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition cryptdefs.c:207
void GWEN_Crypt_Random(int quality, uint8_t *buffer, uint32_t len)
Definition cryptdefs.c:551
int GWEN_Crypt_KeyDataFromText(const char *text, unsigned char *buffer, unsigned int bufLength)
Definition cryptdefs.c:532
static int GWEN_Crypt__KeyDataFromText(const char *text, unsigned char *buffer, unsigned int bufLength)
Definition cryptdefs.c:476
const char * GWEN_Crypt_PinEncoding_toString(GWEN_CRYPT_PINENCODING pe)
Definition cryptdefs.c:77
int GWEN_Crypt__TransformToBCD(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition cryptdefs.c:243
GWEN_CRYPT_PINENCODING
Definition cryptdefs.h:39
@ GWEN_Crypt_PinEncoding_Bcd
Definition cryptdefs.h:43
@ GWEN_Crypt_PinEncoding_FPin2
Definition cryptdefs.h:45
@ GWEN_Crypt_PinEncoding_None
Definition cryptdefs.h:41
@ GWEN_Crypt_PinEncoding_Unknown
Definition cryptdefs.h:40
@ GWEN_Crypt_PinEncoding_Bin
Definition cryptdefs.h:42
@ GWEN_Crypt_PinEncoding_Ascii
Definition cryptdefs.h:44
GWEN_CRYPT_PINTYPE
Definition cryptdefs.h:26
@ GWEN_Crypt_PinType_Access
Definition cryptdefs.h:29
@ GWEN_Crypt_PinType_None
Definition cryptdefs.h:28
@ GWEN_Crypt_PinType_Manage
Definition cryptdefs.h:30
@ GWEN_Crypt_PinType_Unknown
Definition cryptdefs.h:27
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_ERROR_BUFFER_OVERFLOW
Definition error.h:79
#define GWEN_ERROR_BAD_SIZE
Definition error.h:100
#define GWEN_LOGDOMAIN
Definition logger.h:35
int GWEN_MDigest_Begin(GWEN_MDIGEST *md)
Definition mdigest.c:129
int GWEN_MDigest_End(GWEN_MDIGEST *md)
Definition mdigest.c:141
uint8_t * GWEN_MDigest_GetDigestPtr(GWEN_MDIGEST *md)
Definition mdigest.c:81
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition mdigest.c:54
int GWEN_MDigest_Update(GWEN_MDIGEST *md, const uint8_t *buf, unsigned int l)
Definition mdigest.c:153
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Md5_new(void)
Definition mdigestgc.c:140
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Rmd160_new(void)
Definition mdigestgc.c:158
struct GWEN_MDIGEST GWEN_MDIGEST
Definition mdigest.h:25