~ubuntu-branches/ubuntu/trusty/pianobar/trusty

« back to all changes in this revision

Viewing changes to src/libpiano/crypt.c

  • Committer: Package Import Robot
  • Author(s): Luke Faraone
  • Date: 2012-05-06 14:24:34 UTC
  • mfrom: (1.3.9)
  • Revision ID: package-import@ubuntu.com-20120506142434-74kwucnyp97msxdi
Tags: 2012.05.06-1
* New upstream version.
  - JSON api support (closes: #670483, LP: #988395)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
Copyright (c) 2008-2010
 
2
Copyright (c) 2008-2012
3
3
        Lars-Dominik Braun <lars@6xq.net>
4
4
 
5
5
Permission is hereby granted, free of charge, to any person obtaining a copy
22
22
*/
23
23
 
24
24
#include <string.h>
 
25
#include <assert.h>
 
26
#include <gcrypt.h>
25
27
#include <stdio.h>
26
28
#include <stdlib.h>
27
29
#include <stdint.h>
28
 
#include <arpa/inet.h>
29
30
 
30
31
#include "crypt.h"
31
 
#include "crypt_key_output.h"
32
 
#include "crypt_key_input.h"
33
 
#include "piano_private.h"
34
 
 
35
 
#define byteswap32(x) ((((x) >> 24) & 0x000000ff) | \
36
 
                (((x) >> 8) & 0x0000ff00) | \
37
 
                (((x) << 8) & 0x00ff0000) | \
38
 
                (((x) << 24) & 0xff000000))
39
 
 
40
 
#define hostToBigEndian32(x) htonl(x)
41
 
#define bigToHostEndian32(x) ntohl(x)
42
32
 
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
47
39
 */
48
 
#define INITIAL_SHIFT 28
49
 
#define SHIFT_DEC 4
50
 
char *PianoDecryptString (const char * const s) {
51
 
        const unsigned char *strInput = (const unsigned char *) s;
52
 
        /* hex-decode => strlen/2 + null-byte */
53
 
        uint32_t *iDecrypt;
54
 
        char *strDecrypted;
55
 
        unsigned char shift = INITIAL_SHIFT, intsDecoded = 0, j;
56
 
        /* blowfish blocks, 32-bit */
57
 
        uint32_t f, l, r, lrExchange;
58
 
 
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);
 
43
        gcry_error_t gret;
 
44
        unsigned char *output;
 
45
        size_t outputLen = inputLen/2;
 
46
 
 
47
        assert (inputLen%2 == 0);
 
48
 
 
49
        output = calloc (outputLen+1, sizeof (*output));
 
50
        /* hex decode */
 
51
        for (size_t i = 0; i < outputLen; i++) {
 
52
                char hex[3];
 
53
                memcpy (hex, &input[i*2], 2);
 
54
                hex[2] = '\0';
 
55
                output[i] = strtol (hex, NULL, 16);
 
56
        }
 
57
 
 
58
        gret = gcry_cipher_decrypt (h, output, outputLen, NULL, 0);
 
59
        if (gret) {
61
60
                return NULL;
62
61
        }
63
 
        strDecrypted = (char *) iDecrypt;
64
 
 
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;
72
 
                }
73
 
                if (shift > 0) {
74
 
                        shift -= SHIFT_DEC;
75
 
                } else {
76
 
                        shift = INITIAL_SHIFT;
77
 
                        /* initialize next dword */
78
 
                        *(++iDecrypt) = 0;
79
 
                        ++intsDecoded;
80
 
                }
81
 
 
82
 
                /* two 32-bit hex-decoded boxes available => blowfish decrypt */
83
 
                if (intsDecoded == 2) {
84
 
                        l = *(iDecrypt-2);
85
 
                        r = *(iDecrypt-1);
86
 
 
87
 
                        for (j = in_key_n + 1; j > 1; --j) {
88
 
                                l ^= in_key_p [j];
89
 
                                
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];
94
 
                                r ^= f;
95
 
                                /* exchange l & r */
96
 
                                lrExchange = l;
97
 
                                l = r;
98
 
                                r = lrExchange;
99
 
                        }
100
 
                        /* exchange l & r */
101
 
                        lrExchange = l;
102
 
                        l = r;
103
 
                        r = lrExchange;
104
 
                        r ^= in_key_p [1];
105
 
                        l ^= in_key_p [0];
106
 
 
107
 
                        *(iDecrypt-2) = bigToHostEndian32 (l);
108
 
                        *(iDecrypt-1) = bigToHostEndian32 (r);
109
 
 
110
 
                        intsDecoded = 0;
111
 
                }
112
 
                ++strInput;
113
 
        }
114
 
 
115
 
        return strDecrypted;
 
62
 
 
63
        *retSize = outputLen;
 
64
 
 
65
        return (char *) output;
116
66
}
117
 
#undef INITIAL_SHIFT
118
 
#undef SHIFT_DEC
119
67
 
120
68
/*      blowfish-encrypt/hex-encode string
 
69
 *      @param gcrypt handle
121
70
 *      @param encrypt this
122
71
 *      @return encrypted, hex-encoded string
123
72
 */
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;
130
 
        /* output string */
131
 
        unsigned char *strHex, *hexPtr;
132
 
        const char *hexmap = "0123456789abcdef";
133
 
 
134
 
        if ((blockInput = calloc (blockN*2, sizeof (*blockInput))) == NULL) {
135
 
                return NULL;
136
 
        }
137
 
        blockPtr = blockInput;
138
 
 
139
 
        if ((strHex = calloc (blockN*8*2 + 1, sizeof (*strHex))) == NULL) {
140
 
                return NULL;
141
 
        }
142
 
        hexPtr = strHex;
143
 
 
144
 
        memcpy (blockInput, strInput, strInputN);
145
 
 
146
 
        while (blockN > 0) {
147
 
                /* encryption blocks */
148
 
                uint32_t f, lrExchange;
149
 
                register uint32_t l, r;
150
 
                int i;
151
 
 
152
 
                l = hostToBigEndian32 (*blockPtr);
153
 
                r = hostToBigEndian32 (*(blockPtr+1));
154
 
                
155
 
                /* encrypt blocks */
156
 
                for (i = 0; i < out_key_n; i++) {
157
 
                        l ^= out_key_p[i];
158
 
 
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];
163
 
                        r ^= f;
164
 
                        /* exchange l & r */
165
 
                        lrExchange = l;
166
 
                        l = r;
167
 
                        r = lrExchange;
168
 
                }
169
 
                /* exchange l & r again */
170
 
                lrExchange = l;
171
 
                l = r;
172
 
                r = lrExchange;
173
 
                r ^= out_key_p [out_key_n];
174
 
                l ^= out_key_p [out_key_n+1];
175
 
 
176
 
                /* swap bytes again... */
177
 
                l = byteswap32 (l);
178
 
                r = byteswap32 (r);
179
 
 
180
 
                /* hex-encode encrypted blocks */
181
 
                for (i = 0; i < 4; i++) {
182
 
                        *hexPtr++ = hexmap[(l & 0xf0) >> 4];
183
 
                        *hexPtr++ = hexmap[l & 0x0f];
184
 
                        l >>= 8;
185
 
                }
186
 
                for (i = 0; i < 4; i++) {
187
 
                        *hexPtr++ = hexmap[(r & 0xf0) >> 4];
188
 
                        *hexPtr++ = hexmap[r & 0x0f];
189
 
                        r >>= 8;
190
 
                }
191
 
 
192
 
                /* two! 32-bit blocks encrypted (l & r) */
193
 
                blockPtr += 2;
194
 
                --blockN;
195
 
        }
196
 
 
197
 
        free (blockInput);
198
 
 
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);
 
78
        gcry_error_t gret;
 
79
 
 
80
        paddedInput = calloc (paddedInputLen+1, sizeof (*paddedInput));
 
81
        memcpy (paddedInput, s, inputLen);
 
82
 
 
83
        gret = gcry_cipher_encrypt (h, paddedInput, paddedInputLen, NULL, 0);
 
84
        if (gret) {
 
85
                return NULL;
 
86
        }
 
87
 
 
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]);
 
91
        }
 
92
 
 
93
        free (paddedInput);
 
94
 
 
95
        return (char *) hexOutput;
200
96
}
 
97