cryptkeysym.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id: crypttoken.h 1113 2007-01-10 09:14:16Z martin $
00005     begin       : Wed Mar 16 2005
00006     copyright   : (C) 2005 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *          Please see toplevel file COPYING for license details           *
00011  ***************************************************************************/
00012 
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016 
00017 
00018 #include "cryptkeysym_p.h"
00019 #include <gwenhywfar/misc.h>
00020 #include <gwenhywfar/debug.h>
00021 #include <gwenhywfar/cryptdefs.h>
00022 
00023 
00024 
00025 GWEN_INHERIT(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM)
00026 
00027 
00028 
00029 
00030 
00031 
00032 int GWEN_Crypt_KeySym_Encipher(GWEN_CRYPT_KEY *k,
00033                                const uint8_t *pInData,
00034                                uint32_t inLen,
00035                                uint8_t *pOutData,
00036                                uint32_t *pOutLen) {
00037   GWEN_CRYPT_KEY_SYM *xk;
00038   gcry_error_t err;
00039 
00040   assert(k);
00041   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k);
00042   assert(xk);
00043 
00044   err=gcry_cipher_encrypt(xk->algoHandle, pOutData, inLen, pInData, inLen);
00045   if (err) {
00046     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_encrypt(): %s", gcry_strerror(err));
00047     return GWEN_ERROR_GENERIC;
00048   }
00049   *pOutLen=inLen;
00050 
00051   return 0;
00052 }
00053 
00054 
00055 
00056 int GWEN_Crypt_KeySym_Decipher(GWEN_CRYPT_KEY *k,
00057                                const uint8_t *pInData,
00058                                uint32_t inLen,
00059                                uint8_t *pOutData,
00060                                uint32_t *pOutLen) {
00061   GWEN_CRYPT_KEY_SYM *xk;
00062   gcry_error_t err;
00063 
00064   assert(k);
00065   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k);
00066   assert(xk);
00067 
00068   err=gcry_cipher_decrypt(xk->algoHandle, pOutData, inLen, pInData, inLen);
00069   if (err) {
00070     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_decrypt(): %s", gcry_strerror(err));
00071     return GWEN_ERROR_GENERIC;
00072   }
00073   *pOutLen=inLen;
00074 
00075   return 0;
00076 }
00077 
00078 
00079 
00080 GWENHYWFAR_CB
00081 void GWEN_Crypt_KeySym_freeData(void *bp, void *p) {
00082   GWEN_CRYPT_KEY_SYM *xk;
00083 
00084   xk=(GWEN_CRYPT_KEY_SYM*) p;
00085   if (xk->keyData && xk->keyLen) {
00086     memset(xk->keyData, 0, xk->keyLen);
00087     free(xk->keyData);
00088   }
00089   xk->keyData=NULL;
00090   xk->keyLen=0;
00091   if (xk->algoValid)
00092     gcry_cipher_close(xk->algoHandle);
00093   GWEN_FREE_OBJECT(xk);
00094 }
00095 
00096 
00097 
00098 GWEN_CRYPT_KEY *GWEN_Crypt_KeySym_dup(const GWEN_CRYPT_KEY *k) {
00099   GWEN_CRYPT_KEY *nk;
00100   GWEN_CRYPT_KEY_SYM *xk;
00101 
00102   assert(k);
00103   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k);
00104   assert(xk);
00105 
00106   nk=GWEN_Crypt_KeySym_fromData(GWEN_Crypt_Key_GetCryptAlgoId(k),
00107                                 GWEN_Crypt_Key_GetKeySize(k),
00108                                 xk->mode,
00109                                 xk->algo,
00110                                 GCRY_CIPHER_SECURE,
00111                                 xk->keyData,
00112                                 xk->keyLen);
00113   return nk;
00114 }
00115 
00116 
00117 
00118 enum gcry_cipher_modes GWEN_Crypt_KeySym__MyMode2GMode(GWEN_CRYPT_CRYPTMODE mode) {
00119   switch(mode) {
00120   case GWEN_Crypt_CryptMode_Unknown: return GCRY_CIPHER_MODE_NONE;
00121   case GWEN_Crypt_CryptMode_None:    return GCRY_CIPHER_MODE_NONE;
00122   case GWEN_Crypt_CryptMode_Ecb:     return GCRY_CIPHER_MODE_ECB;
00123   case GWEN_Crypt_CryptMode_Cfb:     return GCRY_CIPHER_MODE_CFB;
00124   case GWEN_Crypt_CryptMode_Cbc:     return GCRY_CIPHER_MODE_CBC;
00125   }
00126 
00127   return GCRY_CIPHER_MODE_NONE;
00128 }
00129 
00130 
00131 
00132 GWEN_CRYPT_KEY *GWEN_Crypt_KeySym_Generate(GWEN_CRYPT_CRYPTALGOID cryptAlgoId, int keySize,
00133                                            GWEN_CRYPT_CRYPTMODE mode,
00134                                            int algo,
00135                                            unsigned int flags,
00136                                            int quality) {
00137   GWEN_CRYPT_KEY *k;
00138   GWEN_CRYPT_KEY_SYM *xk;
00139   int kbytes;
00140   uint8_t *keyData;
00141   gcry_error_t err;
00142   enum gcry_random_level q;
00143 
00144   k=GWEN_Crypt_Key_new(cryptAlgoId, keySize);
00145   assert(k);
00146   GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_SYM, xk);
00147   GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k, xk, GWEN_Crypt_KeySym_freeData);
00148   GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeySym_Encipher);
00149   GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeySym_Decipher);
00150 
00151   switch(quality) {
00152   case 0:  q=GCRY_WEAK_RANDOM; break;
00153   case 1:  q=GCRY_STRONG_RANDOM; break;
00154   case 2:
00155   default: q=GCRY_VERY_STRONG_RANDOM; break;
00156   }
00157 
00158   /* open algo */
00159   err=gcry_cipher_open(&xk->algoHandle, algo, GWEN_Crypt_KeySym__MyMode2GMode(mode), flags);
00160   if (err) {
00161     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_open(): %s", gcry_strerror(err));
00162     GWEN_Crypt_Key_free(k);
00163     return NULL;
00164   }
00165   xk->algoValid=1;
00166   xk->mode=mode;
00167 
00168   kbytes=keySize/8;
00169   if (keySize % 8)
00170     kbytes++;
00171   keyData=gcry_random_bytes(kbytes, q);
00172 
00173   /* store key data */
00174   xk->keyData=keyData;
00175   xk->keyLen=kbytes;
00176 
00177   /* set key in algo */
00178   err=gcry_cipher_setkey(xk->algoHandle, xk->keyData, xk->keyLen);
00179   if (err) {
00180     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_setkey(): %s", gcry_strerror(err));
00181     GWEN_Crypt_Key_free(k);
00182     return NULL;
00183   }
00184 
00185   return k;
00186 }
00187 
00188 
00189 
00190 GWEN_CRYPT_KEY *GWEN_Crypt_KeySym_fromData(GWEN_CRYPT_CRYPTALGOID cryptAlgoId, int keySize,
00191                                            GWEN_CRYPT_CRYPTMODE mode,
00192                                            int algo,
00193                                            unsigned int flags,
00194                                            const uint8_t *kd, uint32_t kl) {
00195   GWEN_CRYPT_KEY *k;
00196   GWEN_CRYPT_KEY_SYM *xk;
00197   gcry_error_t err;
00198 
00199   if (kl!=gcry_cipher_get_algo_keylen(algo)) {
00200     DBG_ERROR(GWEN_LOGDOMAIN, "Invalid key length (is %d, should be %d)",
00201               (int)kl, (int)gcry_cipher_get_algo_keylen(algo));
00202     return NULL;
00203   }
00204 
00205   k=GWEN_Crypt_Key_new(cryptAlgoId, keySize);
00206   assert(k);
00207   GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_SYM, xk);
00208   GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k, xk, GWEN_Crypt_KeySym_freeData);
00209   GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeySym_Encipher);
00210   GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeySym_Decipher);
00211 
00212   /* open algo */
00213   err=gcry_cipher_open(&xk->algoHandle, algo, GWEN_Crypt_KeySym__MyMode2GMode(mode), flags);
00214   if (err) {
00215     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_open(): %s", gcry_strerror(err));
00216     GWEN_Crypt_Key_free(k);
00217     return NULL;
00218   }
00219   xk->algoValid=1;
00220   xk->mode=mode;
00221   xk->algo=algo;
00222 
00223   /* read key data */
00224   if (kd==NULL || kl==0) {
00225     DBG_INFO(GWEN_LOGDOMAIN, "No key data");
00226     GWEN_Crypt_Key_free(k);
00227     return NULL;
00228   }
00229 
00230   /* store key data */
00231   xk->keyData=(uint8_t*) malloc(kl);
00232   assert(xk->keyData);
00233   memmove(xk->keyData, kd, kl);
00234   xk->keyLen=kl;
00235 
00236   /* set key in algo */
00237   err=gcry_cipher_setkey(xk->algoHandle, xk->keyData, xk->keyLen);
00238   if (err) {
00239     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_setkey(): %s", gcry_strerror(err));
00240     GWEN_Crypt_Key_free(k);
00241     return NULL;
00242   }
00243 
00244   return k;
00245 }
00246 
00247 
00248 
00249 GWEN_CRYPT_KEY *GWEN_Crypt_KeySym_fromDb(GWEN_CRYPT_CRYPTALGOID cryptAlgoId,
00250                                          GWEN_CRYPT_CRYPTMODE mode,
00251                                          int algo,
00252                                          unsigned int flags,
00253                                          const char *gname,
00254                                          GWEN_DB_NODE *db) {
00255   gcry_error_t err;
00256   GWEN_CRYPT_KEY *k;
00257   GWEN_CRYPT_KEY_SYM *xk;
00258   unsigned int nbits;
00259   GWEN_DB_NODE *dbR;
00260   unsigned int len;
00261   const char *p;
00262 
00263   dbR=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, gname);
00264   if (dbR==NULL) {
00265     DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an %s key (no %s group)",
00266               gname, gname);
00267     return NULL;
00268   }
00269 
00270   k=GWEN_Crypt_Key_fromDb(db);
00271   if (k==NULL) {
00272     DBG_INFO(GWEN_LOGDOMAIN, "here");
00273     return NULL;
00274   }
00275   if (GWEN_Crypt_Key_GetCryptAlgoId(k)!=cryptAlgoId) {
00276     DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an RSA key");
00277     GWEN_Crypt_Key_free(k);
00278     return NULL;
00279   }
00280   nbits=GWEN_Crypt_Key_GetKeySize(k)*8;
00281 
00282   /* extend key */
00283   GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_SYM, xk);
00284   GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k, xk, GWEN_Crypt_KeySym_freeData);
00285   GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeySym_Encipher);
00286   GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeySym_Decipher);
00287 
00288   /* open algo */
00289   err=gcry_cipher_open(&xk->algoHandle, algo, GWEN_Crypt_KeySym__MyMode2GMode(mode), flags);
00290   if (err) {
00291     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_open(): %s", gcry_strerror(err));
00292     GWEN_Crypt_Key_free(k);
00293     return NULL;
00294   }
00295   xk->algoValid=1;
00296   xk->mode=mode;
00297   xk->algo=algo;
00298 
00299   /* read key data */
00300   p=GWEN_DB_GetBinValue(dbR, "keyData", 0, NULL, 0, &len);
00301   if (p==NULL || len==0) {
00302     DBG_INFO(GWEN_LOGDOMAIN, "No key data");
00303     GWEN_Crypt_Key_free(k);
00304     return NULL;
00305   }
00306 
00307   /* store key data */
00308   xk->keyData=(uint8_t*) malloc(len);
00309   assert(xk->keyData);
00310   memmove(xk->keyData, p, len);
00311   xk->keyLen=len;
00312 
00313   /* set key in algo */
00314   err=gcry_cipher_setkey(xk->algoHandle, xk->keyData, xk->keyLen);
00315   if (err) {
00316     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_setkey(): %s", gcry_strerror(err));
00317     GWEN_Crypt_Key_free(k);
00318     return NULL;
00319   }
00320 
00321   return k;
00322 }
00323 
00324 
00325 
00326 int GWEN_Crypt_KeySym_toDb(const GWEN_CRYPT_KEY *k, GWEN_DB_NODE *db, const char *gname) {
00327   GWEN_CRYPT_KEY_SYM *xk;
00328   GWEN_DB_NODE *dbR;
00329   int rv;
00330 
00331   assert(k);
00332   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k);
00333   assert(xk);
00334 
00335   /* let key module wirte basic key info */
00336   rv=GWEN_Crypt_Key_toDb(k, db);
00337   if (rv)
00338     return rv;
00339 
00340   /* write sym stuff into our own group */
00341   dbR=GWEN_DB_GetGroup(db, GWEN_DB_FLAGS_OVERWRITE_GROUPS, gname);
00342   assert(dbR);
00343 
00344   GWEN_DB_SetBinValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
00345                       "keyData", xk->keyData, xk->keyLen);
00346 
00347   return 0;
00348 }
00349 
00350 
00351 
00352 int GWEN_Crypt_KeySym_SetKeyData(GWEN_CRYPT_KEY *k, const uint8_t *kd, uint32_t kl) {
00353   GWEN_CRYPT_KEY_SYM *xk;
00354   gcry_error_t err;
00355 
00356   if (!kd || !kl) {
00357     DBG_ERROR(GWEN_LOGDOMAIN, "Empty keydata not allowed");
00358     return GWEN_ERROR_INVALID;
00359   }
00360 
00361   assert(k);
00362   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k);
00363   assert(xk);
00364 
00365   if (xk->keyData && xk->keyLen) {
00366     memset(xk->keyData, 0, xk->keyLen);
00367     free(xk->keyData);
00368   }
00369 
00370   /* store key data */
00371   xk->keyData=(uint8_t*)malloc(kl);
00372   assert(xk->keyData);
00373   memmove(xk->keyData, kd, kl);
00374   xk->keyLen=kl;
00375 
00376   /* set key in algo */
00377   err=gcry_cipher_setkey(xk->algoHandle, xk->keyData, xk->keyLen);
00378   if (err) {
00379     DBG_INFO(GWEN_LOGDOMAIN, "gcry_cipher_setkey(): %s", gcry_strerror(err));
00380     GWEN_Crypt_Key_free(k);
00381     return GWEN_ERROR_GENERIC;
00382   }
00383 
00384   return 0;
00385 }
00386 
00387 
00388 
00389 uint8_t *GWEN_Crypt_KeySym_GetKeyDataPtr(const GWEN_CRYPT_KEY *k) {
00390   GWEN_CRYPT_KEY_SYM *xk;
00391 
00392   assert(k);
00393   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k);
00394   assert(xk);
00395 
00396   return xk->keyData;
00397 }
00398 
00399 
00400 
00401 uint32_t GWEN_Crypt_KeySym_GetKeyDataLen(const GWEN_CRYPT_KEY *k) {
00402   GWEN_CRYPT_KEY_SYM *xk;
00403 
00404   assert(k);
00405   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_SYM, k);
00406   assert(xk);
00407 
00408   return xk->keyLen;
00409 }
00410 
00411 
00412 
00413 
00414 GWEN_CRYPT_KEY *GWEN_Crypt_KeyDes3K_Generate(GWEN_CRYPT_CRYPTMODE mode,
00415                                              int keySize,
00416                                              int quality){
00417   uint8_t kd[16];
00418   GWEN_CRYPT_KEY *k;
00419 
00420   GWEN_Crypt_Random(quality, kd, 16);
00421   k=GWEN_Crypt_KeyDes3K_fromData(mode, keySize, kd, 16);
00422   memset(kd, 0, 16);
00423 
00424   return k;
00425 }
00426 
00427 
00428 
00429 GWEN_CRYPT_KEY *GWEN_Crypt_KeyDes3K_fromData(GWEN_CRYPT_CRYPTMODE mode, int keySize,
00430                                              const uint8_t *kd, uint32_t kl) {
00431   if (kl==16) {
00432     uint8_t new_kd[24];
00433     GWEN_CRYPT_KEY *k;
00434 
00435     /* 3key DES with only two keys, copy key1 as key3 */
00436     memmove(new_kd, kd, 16);
00437     memmove(new_kd+16, new_kd, 8);
00438     k=GWEN_Crypt_KeySym_fromData(GWEN_Crypt_CryptAlgoId_Des3K, 24,
00439                                  mode, GCRY_CIPHER_3DES, GCRY_CIPHER_SECURE, new_kd, 24);
00440     memset(new_kd, 0, 24);
00441     return k;
00442   }
00443   else
00444     return GWEN_Crypt_KeySym_fromData(GWEN_Crypt_CryptAlgoId_Des3K, keySize,
00445                                       mode, GCRY_CIPHER_3DES, GCRY_CIPHER_SECURE, kd, kl);
00446 }
00447 
00448 
00449 
00450 GWEN_CRYPT_KEY *GWEN_Crypt_KeyDes3K_fromDb(GWEN_CRYPT_CRYPTMODE mode,
00451                                            GWEN_DB_NODE *db) {
00452   return GWEN_Crypt_KeySym_fromDb(GWEN_Crypt_CryptAlgoId_Des3K, mode,
00453                                   GCRY_CIPHER_3DES, GCRY_CIPHER_SECURE, "des3k", db);
00454 }
00455 
00456 
00457 
00458 int GWEN_Crypt_KeyDes3K_toDb(const GWEN_CRYPT_KEY *k, GWEN_DB_NODE *db) {
00459   return GWEN_Crypt_KeySym_toDb(k, db, "des3k");
00460 }
00461 
00462 
00463 
00464 int GWEN_Crypt_KeyDes3K_SetKeyData(GWEN_CRYPT_KEY *k, const uint8_t *kd, uint32_t kl) {
00465   if (kl==16) {
00466     uint8_t new_kd[24];
00467     int rv;
00468 
00469     /* 3key DES with only two keys, copy key1 as key3 */
00470     memmove(new_kd, kd, 16);
00471     memmove(new_kd+16, new_kd, 8);
00472     rv=GWEN_Crypt_KeySym_SetKeyData(k, new_kd, 24);
00473     memset(new_kd, 0, 24);
00474     return rv;
00475   }
00476   else
00477     return GWEN_Crypt_KeySym_SetKeyData(k, kd, kl);
00478 }
00479 
00480 
00481 
00482 uint8_t *GWEN_Crypt_KeyDes3K_GetKeyDataPtr(const GWEN_CRYPT_KEY *k) {
00483   return GWEN_Crypt_KeySym_GetKeyDataPtr(k);
00484 }
00485 
00486 
00487 
00488 uint32_t GWEN_Crypt_KeyDes3K_GetKeyDataLen(const GWEN_CRYPT_KEY *k) {
00489   return GWEN_Crypt_KeySym_GetKeyDataLen(k);
00490 }
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 GWEN_CRYPT_KEY *GWEN_Crypt_KeyBlowFish_Generate(GWEN_CRYPT_CRYPTMODE mode,
00499                                                 int keySize,
00500                                                 int quality){
00501   return GWEN_Crypt_KeySym_Generate(GWEN_Crypt_CryptAlgoId_BlowFish, keySize, mode,
00502                                     GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_SECURE, quality);
00503 }
00504 
00505 
00506 
00507 GWEN_CRYPT_KEY *GWEN_Crypt_KeyBlowFish_fromData(GWEN_CRYPT_CRYPTMODE mode, int keySize,
00508                                                 const uint8_t *kd, uint32_t kl) {
00509   return GWEN_Crypt_KeySym_fromData(GWEN_Crypt_CryptAlgoId_BlowFish, keySize, mode,
00510                                     GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_SECURE,
00511                                     kd, kl);
00512 }
00513 
00514 
00515 
00516 GWEN_CRYPT_KEY *GWEN_Crypt_KeyBlowFish_fromDb(GWEN_CRYPT_CRYPTMODE mode,
00517                                               GWEN_DB_NODE *db) {
00518   return GWEN_Crypt_KeySym_fromDb(GWEN_Crypt_CryptAlgoId_BlowFish, mode,
00519                                   GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_SECURE, "blowFish", db);
00520 }
00521 
00522 
00523 
00524 int GWEN_Crypt_KeyBlowFish_toDb(const GWEN_CRYPT_KEY *k, GWEN_DB_NODE *db) {
00525   return GWEN_Crypt_KeySym_toDb(k, db, "blowFish");
00526 }
00527 
00528 
00529 
00530 int GWEN_Crypt_KeyBlowFish_SetKeyData(GWEN_CRYPT_KEY *k, const uint8_t *kd, uint32_t kl) {
00531   return GWEN_Crypt_KeySym_SetKeyData(k, kd, kl);
00532 }
00533 
00534 
00535 
00536 uint8_t *GWEN_Crypt_KeyBlowFish_GetKeyDataPtr(const GWEN_CRYPT_KEY *k) {
00537   return GWEN_Crypt_KeySym_GetKeyDataPtr(k);
00538 }
00539 
00540 
00541 
00542 uint32_t GWEN_Crypt_KeyBlowFish_GetKeyDataLen(const GWEN_CRYPT_KEY *k) {
00543   return GWEN_Crypt_KeySym_GetKeyDataLen(k);
00544 }
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 

Generated on Fri Apr 11 01:53:46 2008 for gwenhywfar by  doxygen 1.5.5