~ubuntu-branches/ubuntu/wily/pianobar/wily-proposed

« back to all changes in this revision

Viewing changes to libpiano/src/crypt.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Faraone
  • Date: 2011-02-08 17:23:25 UTC
  • mfrom: (1.3.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110208172325-0qf3sxpsu37j5ez9
Tags: 2011.01.24-1
* New upstream version. 
* Switch to DEP5 copyright.
* Augment CFLAGS to use the c99 standard.
* Don't install the now-removed AUTHORS file into docs.
* Drop dep on cmake.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Copyright (c) 2008-2010
3
 
        Lars-Dominik Braun <PromyLOPh@lavabit.com>
4
 
 
5
 
Permission is hereby granted, free of charge, to any person obtaining a copy
6
 
of this software and associated documentation files (the "Software"), to deal
7
 
in the Software without restriction, including without limitation the rights
8
 
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 
copies of the Software, and to permit persons to whom the Software is
10
 
furnished to do so, subject to the following conditions:
11
 
 
12
 
The above copyright notice and this permission notice shall be included in
13
 
all copies or substantial portions of the Software.
14
 
 
15
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 
THE SOFTWARE.
22
 
*/
23
 
 
24
 
#include <string.h>
25
 
#include <stdio.h>
26
 
#include <stdlib.h>
27
 
#include <stdint.h>
28
 
#include <arpa/inet.h>
29
 
 
30
 
#include "crypt_key_output.h"
31
 
#include "crypt_key_input.h"
32
 
#include "piano_private.h"
33
 
 
34
 
#define byteswap32(x) ((((x) >> 24) & 0x000000ff) | \
35
 
                (((x) >> 8) & 0x0000ff00) | \
36
 
                (((x) << 8) & 0x00ff0000) | \
37
 
                (((x) << 24) & 0xff000000))
38
 
 
39
 
#define hostToBigEndian32(x) htonl(x)
40
 
#define bigToHostEndian32(x) ntohl(x)
41
 
 
42
 
/*      decrypt hex-encoded, blowfish-crypted string: decode 2 hex-encoded blocks,
43
 
 *      decrypt, byteswap
44
 
 *      @param hex string
45
 
 *      @return decrypted string or NULL
46
 
 */
47
 
#define INITIAL_SHIFT 28
48
 
#define SHIFT_DEC 4
49
 
unsigned char *PianoDecryptString (const unsigned char *strInput) {
50
 
        /* hex-decode => strlen/2 + null-byte */
51
 
        uint32_t *iDecrypt;
52
 
        unsigned char *strDecrypted;
53
 
        unsigned char shift = INITIAL_SHIFT, intsDecoded = 0, j;
54
 
        /* blowfish blocks, 32-bit */
55
 
        uint32_t f, l, r, lrExchange;
56
 
 
57
 
        if ((iDecrypt = calloc (strlen ((char *) strInput)/2/sizeof (*iDecrypt)+1,
58
 
                        sizeof (*iDecrypt))) == NULL) {
59
 
                return NULL;
60
 
        }
61
 
        strDecrypted = (unsigned char *) iDecrypt;
62
 
 
63
 
        while (*strInput != '\0') {
64
 
                /* hex-decode string */
65
 
                if (*strInput >= '0' && *strInput <= '9') {
66
 
                        *iDecrypt |= (*strInput & 0x0f) << shift;
67
 
                } else if (*strInput >= 'a' && *strInput <= 'f') {
68
 
                        /* 0xa (hex) = 10 (decimal), 'a' & 0x0f == 1 => +9 */
69
 
                        *iDecrypt |= ((*strInput+9) & 0x0f) << shift;
70
 
                }
71
 
                if (shift > 0) {
72
 
                        shift -= SHIFT_DEC;
73
 
                } else {
74
 
                        shift = INITIAL_SHIFT;
75
 
                        /* initialize next dword */
76
 
                        *(++iDecrypt) = 0;
77
 
                        ++intsDecoded;
78
 
                }
79
 
 
80
 
                /* two 32-bit hex-decoded boxes available => blowfish decrypt */
81
 
                if (intsDecoded == 2) {
82
 
                        l = *(iDecrypt-2);
83
 
                        r = *(iDecrypt-1);
84
 
 
85
 
                        for (j = in_key_n + 1; j > 1; --j) {
86
 
                                l ^= in_key_p [j];
87
 
                                
88
 
                                f = in_key_s [0][(l >> 24) & 0xff] +
89
 
                                                in_key_s [1][(l >> 16) & 0xff];
90
 
                                f ^= in_key_s [2][(l >> 8) & 0xff];
91
 
                                f += in_key_s [3][l & 0xff];
92
 
                                r ^= f;
93
 
                                /* exchange l & r */
94
 
                                lrExchange = l;
95
 
                                l = r;
96
 
                                r = lrExchange;
97
 
                        }
98
 
                        /* exchange l & r */
99
 
                        lrExchange = l;
100
 
                        l = r;
101
 
                        r = lrExchange;
102
 
                        r ^= in_key_p [1];
103
 
                        l ^= in_key_p [0];
104
 
 
105
 
                        *(iDecrypt-2) = bigToHostEndian32 (l);
106
 
                        *(iDecrypt-1) = bigToHostEndian32 (r);
107
 
 
108
 
                        intsDecoded = 0;
109
 
                }
110
 
                ++strInput;
111
 
        }
112
 
 
113
 
        return strDecrypted;
114
 
}
115
 
#undef INITIAL_SHIFT
116
 
#undef SHIFT_DEC
117
 
 
118
 
/*      blowfish-encrypt/hex-encode string
119
 
 *      @param encrypt this
120
 
 *      @return encrypted, hex-encoded string
121
 
 */
122
 
unsigned char *PianoEncryptString (const unsigned char *strInput) {
123
 
        const size_t strInputN = strlen ((char *) strInput);
124
 
        /* num of 64-bit blocks, rounded to next block */
125
 
        size_t blockN = strInputN / 8 + 1;
126
 
        uint32_t *blockInput, *blockPtr;
127
 
        /* output string */
128
 
        unsigned char *strHex, *hexPtr;
129
 
        const char *hexmap = "0123456789abcdef";
130
 
 
131
 
        if ((blockInput = calloc (blockN*2, sizeof (*blockInput))) == NULL) {
132
 
                return NULL;
133
 
        }
134
 
        blockPtr = blockInput;
135
 
 
136
 
        if ((strHex = calloc (blockN*8*2 + 1, sizeof (*strHex))) == NULL) {
137
 
                return NULL;
138
 
        }
139
 
        hexPtr = strHex;
140
 
 
141
 
        memcpy (blockInput, strInput, strInputN);
142
 
 
143
 
        while (blockN > 0) {
144
 
                /* encryption blocks */
145
 
                uint32_t f, lrExchange;
146
 
                register uint32_t l, r;
147
 
                int i;
148
 
 
149
 
                l = hostToBigEndian32 (*blockPtr);
150
 
                r = hostToBigEndian32 (*(blockPtr+1));
151
 
                
152
 
                /* encrypt blocks */
153
 
                for (i = 0; i < out_key_n; i++) {
154
 
                        l ^= out_key_p[i];
155
 
 
156
 
                        f = out_key_s[0][(l >> 24) & 0xff] +
157
 
                                        out_key_s[1][(l >> 16) & 0xff];
158
 
                        f ^= out_key_s[2][(l >> 8) & 0xff];
159
 
                        f += out_key_s[3][l & 0xff];
160
 
                        r ^= f;
161
 
                        /* exchange l & r */
162
 
                        lrExchange = l;
163
 
                        l = r;
164
 
                        r = lrExchange;
165
 
                }
166
 
                /* exchange l & r again */
167
 
                lrExchange = l;
168
 
                l = r;
169
 
                r = lrExchange;
170
 
                r ^= out_key_p [out_key_n];
171
 
                l ^= out_key_p [out_key_n+1];
172
 
 
173
 
                /* swap bytes again... */
174
 
                l = byteswap32 (l);
175
 
                r = byteswap32 (r);
176
 
 
177
 
                /* hex-encode encrypted blocks */
178
 
                for (i = 0; i < 4; i++) {
179
 
                        *hexPtr++ = hexmap[(l & 0xf0) >> 4];
180
 
                        *hexPtr++ = hexmap[l & 0x0f];
181
 
                        l >>= 8;
182
 
                }
183
 
                for (i = 0; i < 4; i++) {
184
 
                        *hexPtr++ = hexmap[(r & 0xf0) >> 4];
185
 
                        *hexPtr++ = hexmap[r & 0x0f];
186
 
                        r >>= 8;
187
 
                }
188
 
 
189
 
                /* two! 32-bit blocks encrypted (l & r) */
190
 
                blockPtr += 2;
191
 
                --blockN;
192
 
        }
193
 
 
194
 
        free (blockInput);
195
 
 
196
 
        return strHex;
197
 
}