summaryrefslogtreecommitdiff
path: root/src/libpiano/crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpiano/crypt.c')
-rw-r--r--src/libpiano/crypt.c205
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;
}
+