X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fgc-gnulib.c;h=6eff3e3fee4363f488d28b43f34d0e314a3227ba;hb=8de557e31178699dd6e839850056f0653cdfba89;hp=e0e37b059d9245708b28f25e8380642513e9f385;hpb=3ebed7b6a607af166646a161cddfacddd528b6e0;p=gnulib.git diff --git a/lib/gc-gnulib.c b/lib/gc-gnulib.c index e0e37b059..6eff3e3fe 100644 --- a/lib/gc-gnulib.c +++ b/lib/gc-gnulib.c @@ -37,6 +37,10 @@ #include #include +/* Hashes. */ +#ifdef GC_USE_MD4 +# include "md4.h" +#endif #ifdef GC_USE_MD5 # include "md5.h" #endif @@ -47,10 +51,24 @@ # include "hmac.h" #endif -int +/* Ciphers. */ +#ifdef GC_USE_ARCFOUR +# include "arcfour.h" +#endif +#ifdef GC_USE_ARCTWO +# include "arctwo.h" +#endif +#ifdef GC_USE_DES +# include "des.h" +#endif +#ifdef GC_USE_RIJNDAEL +# include "rijndael-api-fst.h" +#endif + +Gc_rc gc_init (void) { - return 0; + return GC_OK; } void @@ -61,7 +79,7 @@ gc_done (void) /* Randomness. */ -static int +static Gc_rc randomize (int level, char *data, size_t datalen) { int fd; @@ -113,19 +131,19 @@ randomize (int level, char *data, size_t datalen) return GC_OK; } -int +Gc_rc gc_nonce (char *data, size_t datalen) { return randomize (0, data, datalen); } -int +Gc_rc gc_pseudo_random (char *data, size_t datalen) { return randomize (1, data, datalen); } -int +Gc_rc gc_random (char *data, size_t datalen) { return randomize (2, data, datalen); @@ -141,14 +159,341 @@ gc_set_allocators (gc_malloc_t func_malloc, { return; } +/* Ciphers. */ + +typedef struct _gc_cipher_ctx { + Gc_cipher alg; + Gc_cipher_mode mode; +#ifdef GC_USE_ARCTWO + arctwo_context arctwoContext; +#endif +#ifdef GC_USE_ARCFOUR + arcfour_context arcfourContext; +#endif +#ifdef GC_USE_DES + des_ctx desContext; +#endif +#ifdef GC_USE_RIJNDAEL + rijndaelKeyInstance aesEncKey; + rijndaelKeyInstance aesDecKey; + rijndaelCipherInstance aesContext; +#endif +} _gc_cipher_ctx; + +Gc_rc +gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, + gc_cipher_handle * outhandle) +{ + _gc_cipher_ctx *ctx; + Gc_rc rc = GC_OK; + + ctx = calloc (sizeof (*ctx), 1); + + ctx->alg = alg; + ctx->mode = mode; + + switch (alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + switch (mode) + { + case GC_ECB: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + switch (mode) + { + case GC_STREAM: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + switch (mode) + { + case GC_ECB: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + switch (mode) + { + case GC_ECB: + case GC_CBC: + break; + + default: + rc = GC_INVALID_CIPHER; + } + break; +#endif + + default: + rc = GC_INVALID_CIPHER; + } + + if (rc == GC_OK) + *outhandle = ctx; + else + free (ctx); + + return rc; +} + +Gc_rc +gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + arctwo_setkey (&ctx->arctwoContext, keylen, key); + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + arcfour_setkey (&ctx->arcfourContext, key, keylen); + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + if (keylen != 8) + return GC_INVALID_CIPHER; + des_setkey (&ctx->desContext, key); + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + { + rijndael_rc rc; + size_t i; + char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1]; + + for (i = 0; i < keylen; i++) + sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF); + + rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT, + keylen * 8, keyMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + + rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT, + keylen * 8, keyMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + + rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL); + if (rc < 0) + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + switch (ctx->mode) + { + case GC_ECB: + /* Doesn't use IV. */ + break; + + case GC_CBC: + { + rijndael_rc rc; + size_t i; + char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1]; + + for (i = 0; i < ivlen; i++) + sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF); + + rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC, + ivMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + } + break; + + default: + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + arctwo_encrypt (&ctx->arctwoContext, data, data, len); + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + arcfour_stream (&ctx->arcfourContext, data, data, len); + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + for (; len >= 8; len -= 8, data += 8) + des_ecb_encrypt (&ctx->desContext, data, data); + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + { + int nblocks; + + nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey, + data, 8 * len, data); + if (nblocks < 0) + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) +{ + _gc_cipher_ctx *ctx = handle; + + switch (ctx->alg) + { +#ifdef GC_USE_ARCTWO + case GC_ARCTWO40: + arctwo_decrypt (&ctx->arctwoContext, data, data, len); + break; +#endif + +#ifdef GC_USE_ARCFOUR + case GC_ARCFOUR128: + case GC_ARCFOUR40: + arcfour_stream (&ctx->arcfourContext, data, data, len); + break; +#endif + +#ifdef GC_USE_DES + case GC_DES: + for (; len >= 8; len -= 8, data += 8) + des_ecb_decrypt (&ctx->desContext, data, data); + break; +#endif + +#ifdef GC_USE_RIJNDAEL + case GC_AES128: + case GC_AES192: + case GC_AES256: + { + int nblocks; + + nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey, + data, 8 * len, data); + if (nblocks < 0) + return GC_INVALID_CIPHER; + } + break; +#endif + + default: + return GC_INVALID_CIPHER; + } + + return GC_OK; +} + +Gc_rc +gc_cipher_close (gc_cipher_handle handle) +{ + _gc_cipher_ctx *ctx = handle; + + if (ctx) + free (ctx); + + return GC_OK; +} /* Hashes. */ -int +Gc_rc gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) { switch (hash) { +#ifdef GC_USE_MD4 + case GC_MD4: + md4_buffer (in, inlen, resbuf); + break; +#endif + #ifdef GC_USE_MD5 case GC_MD5: md5_buffer (in, inlen, resbuf); @@ -168,40 +513,49 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) return GC_OK; } +#ifdef GC_USE_MD4 +Gc_rc +gc_md4 (const void *in, size_t inlen, void *resbuf) +{ + md4_buffer (in, inlen, resbuf); + return GC_OK; +} +#endif + #ifdef GC_USE_MD5 -int +Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf) { md5_buffer (in, inlen, resbuf); - return 0; + return GC_OK; } #endif #ifdef GC_USE_SHA1 -int +Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf) { sha1_buffer (in, inlen, resbuf); - return 0; + return GC_OK; } #endif #ifdef GC_USE_HMAC_MD5 -int +Gc_rc gc_hmac_md5 (const void *key, size_t keylen, const void *in, size_t inlen, char *resbuf) { hmac_md5 (key, keylen, in, inlen, resbuf); - return 0; + return GC_OK; } #endif #ifdef GC_USE_HMAC_SHA1 -int +Gc_rc gc_hmac_sha1 (const void *key, size_t keylen, const void *in, size_t inlen, char *resbuf) { hmac_sha1 (key, keylen, in, inlen, resbuf); - return 0; + return GC_OK; } #endif