diff options
Diffstat (limited to 'src/libpiano/crypt.c')
-rw-r--r-- | src/libpiano/crypt.c | 205 |
1 files changed, 51 insertions, 154 deletions
diff --git a/src/libpiano/crypt.c b/src/libpiano/crypt.c index 3f98f42..6dafcca 100644 --- a/src/libpiano/crypt.c +++ b/src/libpiano/crypt.c @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2011 +Copyright (c) 2008-2012 Lars-Dominik Braun <lars@6xq.net> Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,23 +22,13 @@ THE SOFTWARE. */ #include <string.h> +#include <assert.h> +#include <gcrypt.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> -#include <arpa/inet.h> #include "crypt.h" -#include "crypt_key_output.h" -#include "crypt_key_input.h" -#include "piano_private.h" - -#define byteswap32(x) ((((x) >> 24) & 0x000000ff) | \ - (((x) >> 8) & 0x0000ff00) | \ - (((x) << 8) & 0x00ff0000) | \ - (((x) << 24) & 0xff000000)) - -#define hostToBigEndian32(x) htonl(x) -#define bigToHostEndian32(x) ntohl(x) /* decrypt hex-encoded, blowfish-crypted string: decode 2 hex-encoded blocks, * decrypt, byteswap @@ -46,162 +36,69 @@ THE SOFTWARE. * @param decrypted string length (without trailing NUL) * @return decrypted string or NULL */ -#define INITIAL_SHIFT 28 -#define SHIFT_DEC 4 -char *PianoDecryptString (const char * const s, size_t * const retSize) { - const unsigned char *strInput = (const unsigned char *) s; - /* hex-decode => strlen/2 + null-byte */ - uint32_t *iDecrypt; - size_t decryptedSize; - char *strDecrypted; - unsigned char shift = INITIAL_SHIFT, intsDecoded = 0, j; - /* blowfish blocks, 32-bit */ - uint32_t f, l, r, lrExchange; - - decryptedSize = strlen ((const char *) strInput)/2; - if ((iDecrypt = calloc (decryptedSize/sizeof (*iDecrypt)+1, - sizeof (*iDecrypt))) == NULL) { - return NULL; - } - strDecrypted = (char *) iDecrypt; - - while (*strInput != '\0') { - /* hex-decode string */ - if (*strInput >= '0' && *strInput <= '9') { - *iDecrypt |= (*strInput & 0x0f) << shift; - } else if (*strInput >= 'a' && *strInput <= 'f') { - /* 0xa (hex) = 10 (decimal), 'a' & 0x0f == 1 => +9 */ - *iDecrypt |= ((*strInput+9) & 0x0f) << shift; - } - if (shift > 0) { - shift -= SHIFT_DEC; - } else { - shift = INITIAL_SHIFT; - /* initialize next dword */ - *(++iDecrypt) = 0; - ++intsDecoded; - } - - /* two 32-bit hex-decoded boxes available => blowfish decrypt */ - if (intsDecoded == 2) { - l = *(iDecrypt-2); - r = *(iDecrypt-1); - - for (j = in_key_n + 1; j > 1; --j) { - l ^= in_key_p [j]; - - f = in_key_s [0][(l >> 24) & 0xff] + - in_key_s [1][(l >> 16) & 0xff]; - f ^= in_key_s [2][(l >> 8) & 0xff]; - f += in_key_s [3][l & 0xff]; - r ^= f; - /* exchange l & r */ - lrExchange = l; - l = r; - r = lrExchange; - } - /* exchange l & r */ - lrExchange = l; - l = r; - r = lrExchange; - r ^= in_key_p [1]; - l ^= in_key_p [0]; - - *(iDecrypt-2) = bigToHostEndian32 (l); - *(iDecrypt-1) = bigToHostEndian32 (r); - - intsDecoded = 0; - } - ++strInput; +char *PianoDecryptString (const char * const input, size_t * const retSize) { + size_t inputLen = strlen (input); + gcry_error_t gret; + unsigned char *output; + size_t outputLen = inputLen/2; + + assert (inputLen%2 == 0); + + output = calloc (outputLen+1, sizeof (*output)); + /* hex decode */ + for (size_t i = 0; i < outputLen; i++) { + char hex[3]; + memcpy (hex, &input[i*2], 2); + hex[2] = '\0'; + output[i] = strtol (hex, NULL, 16); } - if (retSize != NULL) { - *retSize = decryptedSize; + gcry_cipher_hd_t h; + gcry_cipher_open (&h, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0); + gcry_cipher_setkey (h, (unsigned char *) "R=U!LH$O2B#", 11); + gret = gcry_cipher_decrypt (h, output, outputLen, NULL, 0); + if (gret) { + fprintf (stderr, "Failure: %s/%s\n", gcry_strsource (gret), gcry_strerror (gret)); + return NULL; } - return strDecrypted; + gcry_cipher_close (h); + *retSize = outputLen; + + return (char *) output; } -#undef INITIAL_SHIFT -#undef SHIFT_DEC /* blowfish-encrypt/hex-encode string * @param encrypt this * @return encrypted, hex-encoded string */ char *PianoEncryptString (const char *s) { - const unsigned char *strInput = (const unsigned char *) s; - const size_t strInputN = strlen ((const char *) strInput); - /* num of 64-bit blocks, rounded to next block */ - size_t blockN = strInputN / 8 + 1; - uint32_t *blockInput, *blockPtr; - /* output string */ - unsigned char *strHex, *hexPtr; - const char *hexmap = "0123456789abcdef"; - - if ((blockInput = calloc (blockN*2, sizeof (*blockInput))) == NULL) { + unsigned char *paddedInput, *hexOutput; + size_t inputLen = strlen (s); + /* blowfish expects two 32 bit blocks */ + size_t paddedInputLen = (inputLen % 8 == 0) ? inputLen : inputLen + (8-inputLen%8); + gcry_error_t gret; + + paddedInput = calloc (paddedInputLen+1, sizeof (*paddedInput)); + memcpy (paddedInput, s, inputLen); + + gcry_cipher_hd_t h; + gcry_cipher_open (&h, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0); + gcry_cipher_setkey (h, (unsigned char *) "6#26FRL$ZWD", 11); + gret = gcry_cipher_encrypt (h, paddedInput, paddedInputLen, NULL, 0); + if (gret) { + fprintf (stderr, "Failure: %s/%s\n", gcry_strsource (gret), gcry_strerror (gret)); return NULL; } - blockPtr = blockInput; - if ((strHex = calloc (blockN*8*2 + 1, sizeof (*strHex))) == NULL) { - return NULL; - } - hexPtr = strHex; - - memcpy (blockInput, strInput, strInputN); - - while (blockN > 0) { - /* encryption blocks */ - uint32_t f, lrExchange; - register uint32_t l, r; - int i; - - l = hostToBigEndian32 (*blockPtr); - r = hostToBigEndian32 (*(blockPtr+1)); - - /* encrypt blocks */ - for (i = 0; i < out_key_n; i++) { - l ^= out_key_p[i]; - - f = out_key_s[0][(l >> 24) & 0xff] + - out_key_s[1][(l >> 16) & 0xff]; - f ^= out_key_s[2][(l >> 8) & 0xff]; - f += out_key_s[3][l & 0xff]; - r ^= f; - /* exchange l & r */ - lrExchange = l; - l = r; - r = lrExchange; - } - /* exchange l & r again */ - lrExchange = l; - l = r; - r = lrExchange; - r ^= out_key_p [out_key_n]; - l ^= out_key_p [out_key_n+1]; - - /* swap bytes again... */ - l = byteswap32 (l); - r = byteswap32 (r); - - /* hex-encode encrypted blocks */ - for (i = 0; i < 4; i++) { - *hexPtr++ = hexmap[(l & 0xf0) >> 4]; - *hexPtr++ = hexmap[l & 0x0f]; - l >>= 8; - } - for (i = 0; i < 4; i++) { - *hexPtr++ = hexmap[(r & 0xf0) >> 4]; - *hexPtr++ = hexmap[r & 0x0f]; - r >>= 8; - } - - /* two! 32-bit blocks encrypted (l & r) */ - blockPtr += 2; - --blockN; + hexOutput = calloc (paddedInputLen*2+1, sizeof (*hexOutput)); + for (size_t i = 0; i < paddedInputLen; i++) { + snprintf ((char * restrict) &hexOutput[i*2], 3, "%02x", paddedInput[i]); } - free (blockInput); + gcry_cipher_close (h); + free (paddedInput); - return (char *) strHex; + return (char *) hexOutput; } + |