24
24
#include <string.h>
26
28
#include <stdlib.h>
27
29
#include <stdint.h>
28
#include <arpa/inet.h>
31
#include "crypt_key_output.h"
32
#include "crypt_key_input.h"
33
#include "piano_private.h"
35
#define byteswap32(x) ((((x) >> 24) & 0x000000ff) | \
36
(((x) >> 8) & 0x0000ff00) | \
37
(((x) << 8) & 0x00ff0000) | \
38
(((x) << 24) & 0xff000000))
40
#define hostToBigEndian32(x) htonl(x)
41
#define bigToHostEndian32(x) ntohl(x)
43
33
/* decrypt hex-encoded, blowfish-crypted string: decode 2 hex-encoded blocks,
44
34
* decrypt, byteswap
35
* @param gcrypt handle
45
36
* @param hex string
37
* @param decrypted string length (without trailing NUL)
46
38
* @return decrypted string or NULL
48
#define INITIAL_SHIFT 28
50
char *PianoDecryptString (const char * const s) {
51
const unsigned char *strInput = (const unsigned char *) s;
52
/* hex-decode => strlen/2 + null-byte */
55
unsigned char shift = INITIAL_SHIFT, intsDecoded = 0, j;
56
/* blowfish blocks, 32-bit */
57
uint32_t f, l, r, lrExchange;
59
if ((iDecrypt = calloc (strlen ((const char *) strInput)/2/sizeof (*iDecrypt)+1,
60
sizeof (*iDecrypt))) == NULL) {
40
char *PianoDecryptString (gcry_cipher_hd_t h, const char * const input,
41
size_t * const retSize) {
42
size_t inputLen = strlen (input);
44
unsigned char *output;
45
size_t outputLen = inputLen/2;
47
assert (inputLen%2 == 0);
49
output = calloc (outputLen+1, sizeof (*output));
51
for (size_t i = 0; i < outputLen; i++) {
53
memcpy (hex, &input[i*2], 2);
55
output[i] = strtol (hex, NULL, 16);
58
gret = gcry_cipher_decrypt (h, output, outputLen, NULL, 0);
63
strDecrypted = (char *) iDecrypt;
65
while (*strInput != '\0') {
66
/* hex-decode string */
67
if (*strInput >= '0' && *strInput <= '9') {
68
*iDecrypt |= (*strInput & 0x0f) << shift;
69
} else if (*strInput >= 'a' && *strInput <= 'f') {
70
/* 0xa (hex) = 10 (decimal), 'a' & 0x0f == 1 => +9 */
71
*iDecrypt |= ((*strInput+9) & 0x0f) << shift;
76
shift = INITIAL_SHIFT;
77
/* initialize next dword */
82
/* two 32-bit hex-decoded boxes available => blowfish decrypt */
83
if (intsDecoded == 2) {
87
for (j = in_key_n + 1; j > 1; --j) {
90
f = in_key_s [0][(l >> 24) & 0xff] +
91
in_key_s [1][(l >> 16) & 0xff];
92
f ^= in_key_s [2][(l >> 8) & 0xff];
93
f += in_key_s [3][l & 0xff];
107
*(iDecrypt-2) = bigToHostEndian32 (l);
108
*(iDecrypt-1) = bigToHostEndian32 (r);
65
return (char *) output;
120
68
/* blowfish-encrypt/hex-encode string
69
* @param gcrypt handle
121
70
* @param encrypt this
122
71
* @return encrypted, hex-encoded string
124
char *PianoEncryptString (const char *s) {
125
const unsigned char *strInput = (const unsigned char *) s;
126
const size_t strInputN = strlen ((const char *) strInput);
127
/* num of 64-bit blocks, rounded to next block */
128
size_t blockN = strInputN / 8 + 1;
129
uint32_t *blockInput, *blockPtr;
131
unsigned char *strHex, *hexPtr;
132
const char *hexmap = "0123456789abcdef";
134
if ((blockInput = calloc (blockN*2, sizeof (*blockInput))) == NULL) {
137
blockPtr = blockInput;
139
if ((strHex = calloc (blockN*8*2 + 1, sizeof (*strHex))) == NULL) {
144
memcpy (blockInput, strInput, strInputN);
147
/* encryption blocks */
148
uint32_t f, lrExchange;
149
register uint32_t l, r;
152
l = hostToBigEndian32 (*blockPtr);
153
r = hostToBigEndian32 (*(blockPtr+1));
156
for (i = 0; i < out_key_n; i++) {
159
f = out_key_s[0][(l >> 24) & 0xff] +
160
out_key_s[1][(l >> 16) & 0xff];
161
f ^= out_key_s[2][(l >> 8) & 0xff];
162
f += out_key_s[3][l & 0xff];
169
/* exchange l & r again */
173
r ^= out_key_p [out_key_n];
174
l ^= out_key_p [out_key_n+1];
176
/* swap bytes again... */
180
/* hex-encode encrypted blocks */
181
for (i = 0; i < 4; i++) {
182
*hexPtr++ = hexmap[(l & 0xf0) >> 4];
183
*hexPtr++ = hexmap[l & 0x0f];
186
for (i = 0; i < 4; i++) {
187
*hexPtr++ = hexmap[(r & 0xf0) >> 4];
188
*hexPtr++ = hexmap[r & 0x0f];
192
/* two! 32-bit blocks encrypted (l & r) */
199
return (char *) strHex;
73
char *PianoEncryptString (gcry_cipher_hd_t h, const char *s) {
74
unsigned char *paddedInput, *hexOutput;
75
size_t inputLen = strlen (s);
76
/* blowfish expects two 32 bit blocks */
77
size_t paddedInputLen = (inputLen % 8 == 0) ? inputLen : inputLen + (8-inputLen%8);
80
paddedInput = calloc (paddedInputLen+1, sizeof (*paddedInput));
81
memcpy (paddedInput, s, inputLen);
83
gret = gcry_cipher_encrypt (h, paddedInput, paddedInputLen, NULL, 0);
88
hexOutput = calloc (paddedInputLen*2+1, sizeof (*hexOutput));
89
for (size_t i = 0; i < paddedInputLen; i++) {
90
snprintf ((char * restrict) &hexOutput[i*2], 3, "%02x", paddedInput[i]);
95
return (char *) hexOutput;