diff options
Diffstat (limited to 'runtime/libgcry.c')
-rw-r--r-- | runtime/libgcry.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/runtime/libgcry.c b/runtime/libgcry.c new file mode 100644 index 00000000..8184c160 --- /dev/null +++ b/runtime/libgcry.c @@ -0,0 +1,224 @@ +/* gcry.c - rsyslog's libgcrypt based crypto provider + * + * Copyright 2013 Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include <stdio.h> +#include <gcrypt.h> + +#include "rsyslog.h" +#include "libgcry.h" + + +static inline gcryfile +gcryfileConstruct(gcryctx ctx) +{ + gcryfile gf; + if((gf = calloc(1, sizeof(struct gcryfile_s))) == NULL) + goto done; + gf->ctx = ctx; +done: return gf; +} +gcryctx +gcryCtxNew(void) +{ + gcryctx ctx; + ctx = calloc(1, sizeof(struct gcryctx_s)); + return ctx; +} + +int +gcryfileDestruct(gcryfile gf) +{ + int r = 0; + if(gf == NULL) + goto done; + + free(gf); +done: return r; +} +void +rsgcryCtxDel(gcryctx ctx) +{ + if(ctx != NULL) { + free(ctx); + } +} + +static inline void +addPadding(gcryfile pF, uchar *buf, size_t *plen) +{ + unsigned i; + size_t nPad; + nPad = (pF->blkLength - *plen % pF->blkLength) % pF->blkLength; + dbgprintf("DDDD: addPadding %d chars, blkLength %d, mod %d, pad %d\n", + *plen, pF->blkLength, *plen % pF->blkLength, nPad); + for(i = 0 ; i < nPad ; ++i) + buf[(*plen)+i] = 0x00; + (*plen)+= nPad; +} + +static inline void +removePadding(char *buf, size_t *plen) +{ + unsigned len = (unsigned) *plen; + unsigned iSrc, iDst; + char *frstNUL; + + frstNUL = strchr(buf, 0x00); + if(frstNUL == NULL) + goto done; + iDst = iSrc = frstNUL - buf; + + while(iSrc < len) { + if(buf[iSrc] != 0x00) + buf[iDst++] = buf[iSrc]; + ++iSrc; + } + + *plen = iDst; +done: return; +} + +rsRetVal +rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, int gcry_mode, char *iniVector) +{ + #define GCRY_CIPHER GCRY_CIPHER_3DES // TODO: make configurable + size_t keyLength; + char *aesSymKey = "123456789012345678901234"; // TODO: TEST ONLY + gcry_error_t gcryError; + gcryfile gf = NULL; + DEFiRet; + + CHKmalloc(gf = gcryfileConstruct(ctx)); + + gf->blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER); + keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER); + + gcryError = gcry_cipher_open( + &gf->chd, // gcry_cipher_hd_t * + GCRY_CIPHER, // int + gcry_mode, // int + 0); // unsigned int + if (gcryError) { + dbgprintf("gcry_cipher_open failed: %s/%s\n", + gcry_strsource(gcryError), + gcry_strerror(gcryError)); + ABORT_FINALIZE(RS_RET_ERR); + } + + gcryError = gcry_cipher_setkey(gf->chd, aesSymKey, keyLength); + if (gcryError) { + dbgprintf("gcry_cipher_setkey failed: %s/%s\n", + gcry_strsource(gcryError), + gcry_strerror(gcryError)); + ABORT_FINALIZE(RS_RET_ERR); + } + + gcryError = gcry_cipher_setiv(gf->chd, iniVector, gf->blkLength); + if (gcryError) { + dbgprintf("gcry_cipher_setiv failed: %s/%s\n", + gcry_strsource(gcryError), + gcry_strerror(gcryError)); + ABORT_FINALIZE(RS_RET_ERR); + } + *pgf = gf; +finalize_it: + if(iRet != RS_RET_OK && gf != NULL) + gcryfileDestruct(gf); + RETiRet; +} + +int +rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len) +{ + int gcryError; + DEFiRet; + + if(*len == 0) + FINALIZE; + + addPadding(pF, buf, len); + gcryError = gcry_cipher_encrypt(pF->chd, buf, *len, NULL, 0); + if(gcryError) { + dbgprintf("gcry_cipher_encrypt failed: %s/%s\n", + gcry_strsource(gcryError), + gcry_strerror(gcryError)); + ABORT_FINALIZE(RS_RET_ERR); + } +finalize_it: + RETiRet; +} + + +/* module-init dummy for potential later use */ +int +rsgcryInit(void) +{ + return 0; +} + +/* module-deinit dummy for potential later use */ +void +rsgcryExit(void) +{ + return; +} + +#if 0 // we use this for the tool, only! +static void +doDeCrypt(FILE *fpin, FILE *fpout) +{ + gcry_error_t gcryError; + char buf[64*1024]; + size_t nRead, nWritten; + size_t nPad; + + while(1) { + nRead = fread(buf, 1, sizeof(buf), fpin); + if(nRead == 0) + break; + nPad = (blkLength - nRead % blkLength) % blkLength; + fprintf(stderr, "read %d chars, blkLength %d, mod %d, pad %d\n", nRead, blkLength, + nRead % blkLength, nPad); + gcryError = gcry_cipher_decrypt( + gcryCipherHd, // gcry_cipher_hd_t + buf, // void * + nRead, // size_t + NULL, // const void * + 0); // size_t + if (gcryError) { + fprintf(stderr, "gcry_cipher_encrypt failed: %s/%s\n", + gcry_strsource(gcryError), + gcry_strerror(gcryError)); + return; + } +fprintf(stderr, "in remove pad, %d\n", nRead); + removePadding(buf, &nRead); +fprintf(stderr, "out remove pad %d\n", nRead); + nWritten = fwrite(buf, 1, nRead, fpout); + if(nWritten != nRead) { + perror("fpout"); + return; + } + } +} +#endif |