File: Gcrypt.k

package info (click to toggle)
kaya 0.4.2-4
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 4,448 kB
  • ctags: 1,694
  • sloc: cpp: 9,536; haskell: 7,461; sh: 3,013; yacc: 910; makefile: 816; perl: 90
file content (410 lines) | stat: -rw-r--r-- 18,429 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
/** -*-C-*-ish
    Kaya standard library
    Copyright (C) 2004, 2005 Edwin Brady

    This file is distributed under the terms of the GNU Lesser General
    Public Licence. See COPYING for licence.
*/
"<summary>libgcrypt interface</summary>
<prose>This module implements an interface to the <link url='http://directory.fsf.org/security/libgcrypt.html'>libgcrypt</link> cryptographic library. It is used by the <moduleref>Crypto</moduleref> library to provide Kaya's application secret key encryption and decryption. As well as cryptographic algorithms, this library also provides several hash algorithms.</prose>"
module Gcrypt;

import Prelude;
import Binary;

%include "gcrypt.h";
%include "gcrypt_glue.h";
%link "gcrypt";
%imported "gcrypt_glue";

"<summary>Available symmetric ciphers</summary>
<prose>The available symmetric ciphers. <moduleref>Crypto</moduleref> uses <code>AES256</code>.</prose>
<related><functionref>openCipher</functionref></related>"
public data Cipher 
            = Idea | TripleDES | Cast5 | Blowfish | AES128 | AES192
            | AES256 | Twofish | Twofish128 | Arcfour | DES;

"<summary>Cipher modes</summary>
<prose>Cipher modes, <moduleref>Crypto</moduleref> uses <code>CBC</code>.</prose>
<related><functionref>openCipher</functionref></related>"
public data CipherMode = ECB | CFB | CBC | Stream | OFB | CTR;

"<summary>Hash algorithms</summary>
<prose>Hash algorithms</prose>
<related><functionref>openHash</functionref></related>"
public data Hash = SHA1 | RMD160 | MD5 | MD4 | Tiger | SHA256 | CRC32;

"<summary>A cipher handle</summary>
<prose>A cipher handle. Encryption and decryption operations use these.</prose>
<related><functionref>openCipher</functionref></related>"
abstract data CipherHandle(Ptr ptr);
"<summary>A hash handle</summary>
<prose>A hash handle for hashing operations.</prose>
<related><functionref>openHash</functionref></related>"
abstract data HashHandle(Ptr ptr);

type Key = [Int];
type IVec = [Int];

foreign "libgcrypt" {
    Int algo(Cipher c) = cipheralgo;
    Int mode(CipherMode c) = ciphermode;
    Int hashalgo(Hash c) = hashalgo;
    Ptr do_cipherOpen(Cipher algo, CipherMode mode, Int flags) = cipherOpen;
    Void do_cipherClose(Ptr h) = cipherClose;
    Void do_setkey(Ptr h, Key key) = do_setkey;
    Void do_setivec(Ptr h, IVec key) = do_setivec;

    Ptr do_encrypt(Ptr h, Ptr dat, Int size, intval outsize) = do_encrypt;
    Ptr do_decrypt(Ptr h, Ptr dat, Int size, intval outsize) = do_decrypt;

    Int do_cipherKeySize(Int c) = cipherKeySize;
    Int do_cipherBlockLength(Int c) = cipherBlockLength;

    Ptr do_hashOpen(Hash algo, Int flags) = hashOpen;
    Void do_hashClose(Ptr h) = hashClose;
    Void do_hashReset(Ptr h) = hashReset;
    Void do_hashWrite(Ptr h, Ptr dat, Int size) = hashWrite;
    Void do_hashFinal(Ptr h) = hashFinal;
    Ptr do_hashGet(Ptr h, intval size) = hashGet;

    [Int] do_appKey() = appKey;
    [Int] do_appIVec() = appIVec;
}

"<summary>Cipher opening flags</summary>
<prose>Flags for opening ciphers. <code>CipherCTS</code> and <code>CipherMAC</code> may not be used simultaneously.</prose>
<list>
<item><code>CipherSecure</code>: Allocate cipher operations in secure memory if possible.</item>
<item><code>CipherSync</code>: Enable the CFB sync mode.</item>
<item><code>CipherCTS</code>: Enable cipher text stealing (CTS) for the CBC mode</item>
<item><code>CipherMAC</code>: Compute CBC-MAC checksums.</item>
</list>
<related><functionref>openCipher</functionref></related>"
public data CipherFlags = CipherSecure | CipherSync | CipherCTS | CipherMAC;

"<summary>Hash opening flags</summary>
<prose>Flags for opening hashes.</prose>
<list>
<item><code>HashSecure</code>: Allocate hash operations in secure memory if possible.</item>
</list>
<related><functionref>openHash</functionref></related>"
//public data HashFlags = HashSecure | HashHMAC;
// we don't currently have a way to make use of HMAC
public data HashFlags = HashSecure;

"<argument name='algo'>The cipher algorithm to use</argument>
<argument name='mode'>The cipher mode to use</argument>
<argument name='flags'>The flags to use</argument>
<summary>Open a cipher handle</summary>
<prose>Open a cipher handle to be used in cipher operations.</prose>
<related><dataref>CipherFlags</dataref></related>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>closeCipher</functionref></related>
<related><functionref>decrypt</functionref></related>
<related><functionref>decryptString</functionref></related>
<related><functionref>encrypt</functionref></related>
<related><functionref>encryptString</functionref></related>
<related><functionref>setCipherIVec</functionref></related>
<related><functionref>setCipherKey</functionref></related>"
public CipherHandle openCipher(Cipher algo, CipherMode mode, [CipherFlags] flags = createArray(1))
{
    cflags = 0;
    if (elem(CipherSecure,flags)) { cflags += 1; }
    if (elem(CipherSync,flags)) { cflags += 2; }
    if (elem(CipherCTS,flags)) { cflags += 4; }
    if (elem(CipherMAC,flags)) { cflags += 8; }

    return CipherHandle(do_cipherOpen(algo,mode,cflags));
}

"<argument name='h'>The cipher handle</argument>
<summary>Close a cipher handle</summary>
<prose>Close a cipher handle. You should always close cipher handles once you have finished using them.</prose>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>decrypt</functionref></related>
<related><functionref>decryptString</functionref></related>
<related><functionref>encrypt</functionref></related>
<related><functionref>encryptString</functionref></related>
<related><functionref>openCipher</functionref></related>
<related><functionref>setCipherIVec</functionref></related>
<related><functionref>setCipherKey</functionref></related>"
public Void closeCipher(CipherHandle h)
{
    do_cipherClose(h.ptr);
}

"<argument name='h'>The cipher handle</argument>
<argument name='key'>The secret key</argument>
<summary>Set the cipher secret key</summary>
<prose>Sets the cipher secret key. The length of the key depends on the cipher algorithm, and can be found with <functionref>cipherKeySize</functionref>.</prose>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>cipherKeySize</functionref></related>
<related><functionref>closeCipher</functionref></related>
<related><functionref>decrypt</functionref></related>
<related><functionref>decryptString</functionref></related>
<related><functionref>encrypt</functionref></related>
<related><functionref>encryptString</functionref></related>
<related><functionref>openCipher</functionref></related>
<related><functionref>setCipherIVec</functionref></related>"
public Void setCipherKey(CipherHandle h, Key key)
{
    // TODO: Check that key length is right. If not, pad/chop
    do_setkey(h.ptr,key);
}

"<argument name='h'>The cipher handle</argument>
<argument name='key'>The initialisation vector</argument>
<summary>Set the cipher initialisation vector</summary>
<prose>Sets the cipher initialisation vector. The length of the vector depends on the cipher algorithm, and can be found with <functionref>cipherBlockLength</functionref>. Unlike the key, the initialisation vector does not need to be secret.</prose>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>cipherBlockLength</functionref></related>
<related><functionref>closeCipher</functionref></related>
<related><functionref>decrypt</functionref></related>
<related><functionref>decryptString</functionref></related>
<related><functionref>encrypt</functionref></related>
<related><functionref>encryptString</functionref></related>
<related><functionref>openCipher</functionref></related>
<related><functionref>setCipherKey</functionref></related>"
public Void setCipherIVec(CipherHandle h, IVec key)
{
    // TODO: Check that ivec length is right. If not, pad/chop
    do_setivec(h.ptr,key);
}

"<summary>Get the application secret key</summary>
<prose>Get the application secret key. This is mainly provided for the benefit of <functionref>Crypto::encode</functionref>, but may be useful for other functions.</prose>
<related><functionref>appIVec</functionref></related>"
public [Int] appKey()
{
    return do_appKey();
}

"<summary>Get the application initialisation vector</summary>
<prose>Get the application initialisation vector. This is mainly provided for the benefit of <functionref>Crypto::encode</functionref>, but may be useful for other functions.</prose>
<related><functionref>appKey</functionref></related>"
public [Int] appIVec()
{
    return do_appIVec();
}

"<argument name='c'>A cipher algorithm</argument>
<summary>Get the required key size.</summary>
<prose>Get the required key size for a given cipher.</prose>
<related><dataref>Cipher</dataref></related>
<related><functionref>cipherBlockLength</functionref></related>"
public Int cipherKeySize(Cipher c) {
    return do_cipherKeySize(algo(c));
}

"<argument name='c'>A cipher algorithm</argument>
<summary>Get the required block length.</summary>
<prose>Get the required block length for a given cipher.</prose>
<related><dataref>Cipher</dataref></related>
<related><functionref>cipherBlockLength</functionref></related>"
public Int cipherBlockLength(Cipher c) {
    return do_cipherBlockLength(algo(c));
}

"<argument name='h'>A cipher handle</argument>
<argument name='dat'>A block of <moduleref>Binary</moduleref> data</argument>
<summary>Encrypt binary data</summary>
<prose>Encrypts binary data with the given cipher handle, returning a binary block containing the encrypted data.</prose>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>closeCipher</functionref></related>
<related><functionref>decrypt</functionref></related>
<related><functionref>decryptString</functionref></related>
<related><functionref>encryptString</functionref></related>
<related><functionref>openCipher</functionref></related>
<related><functionref>setCipherIVec</functionref></related>
<related><functionref>setCipherKey</functionref></related>"
public Binary encrypt(CipherHandle h, Binary dat)
{
//    putStrLn("Encrypting block of length "+blockSize(dat));
    outlen = 0;
    ptr = do_encrypt(h.ptr, blockData(dat), blockSize(dat), outlen);

//    putStrLn("Got block of length "+outlen);
    return createInitialisedBlock(ptr, outlen);
}

"<argument name='h'>A cipher handle</argument>
<argument name='dat'>A block of encrypted <moduleref>Binary</moduleref> data</argument>
<summary>Decrypt binary data</summary>
<prose>Decrypts binary data with the given cipher handle, returning a binary block containing the decrypted data.</prose>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>closeCipher</functionref></related>
<related><functionref>decryptString</functionref></related>
<related><functionref>encrypt</functionref></related>
<related><functionref>encryptString</functionref></related>
<related><functionref>openCipher</functionref></related>
<related><functionref>setCipherIVec</functionref></related>
<related><functionref>setCipherKey</functionref></related>"
public Binary decrypt(CipherHandle h, Binary dat)
{
    outlen = 0;
    ptr = do_decrypt(h.ptr, blockData(dat), blockSize(dat), outlen);
    return createInitialisedBlock(ptr, outlen);
}

"<argument name='h'>A cipher handle</argument>
<argument name='x'>A string</argument>
<summary>Encrypt a string</summary>
<prose>Encrypts a string with the given cipher handle, returning a base64-encoded string containing the encrypted data.</prose>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>closeCipher</functionref></related>
<related><functionref>decrypt</functionref></related>
<related><functionref>decryptString</functionref></related>
<related><functionref>encrypt</functionref></related>
<related><functionref>openCipher</functionref></related>
<related><functionref>setCipherIVec</functionref></related>
<related><functionref>setCipherKey</functionref></related>"
public String encryptString(CipherHandle h, String x)
{
    block = createBlock(byteLength(x)+1);

//    putStrLn("Encrypting "+x);
    pokeString(block,0,x);
    cryptblock = encrypt(h,block);

//    putStrLn(String(peek(cryptblock,0)));
//    putStrLn(String(peek(cryptblock,1)));
//    putStrLn(String(peek(cryptblock,2)));
    return Binary::base64Encode(cryptblock);
}

"<argument name='h'>A cipher handle</argument>
<argument name='x'>A base64-encoded encrypted string</argument>
<summary>Decrypt a string</summary>
<prose>Decrypts a string with the given cipher handle, returning the unencrypted string.</prose>
<related><dataref>CipherHandle</dataref></related>
<related><functionref>closeCipher</functionref></related>
<related><functionref>decrypt</functionref></related>
<related><functionref>encrypt</functionref></related>
<related><functionref>encryptString</functionref></related>
<related><functionref>openCipher</functionref></related>
<related><functionref>setCipherIVec</functionref></related>
<related><functionref>setCipherKey</functionref></related>"
public String decryptString(CipherHandle h, String x)
{
    block = Binary::base64Decode(x);
    decryptblock = decrypt(h,block);
    return peekString(decryptblock,0);
}

// rewrite to use sensible flags parameter!
"<argument name='algo'>The hash algorithm</argument>
<argument name='flags'>The flags to use</argument>
<summary>Open a hash handle</summary>
<prose>Open a hash handle with the specified algorithm</prose>
<related><dataref>HashFlags</dataref></related>
<related><dataref>HashHandle</dataref></related>
<related><functionref>closeHash</functionref></related>
<related><functionref>finalHash</functionref></related>
<related><functionref>getHash</functionref></related>
<related><functionref>hashBinary</functionref></related>
<related><functionref>hashString</functionref></related>
<related><functionref>resetHash</functionref></related>"
public  HashHandle openHash(Hash algo, [HashFlags] flags = createArray(1))
{
    hflags = 0;
    if (elem(HashSecure,flags)) { hflags += 1; }
    //    if (elem(HashHMAC,flags)) { hflags += 2; }
    return HashHandle(do_hashOpen(algo,hflags));
}

"<argument name='h'>The hash handle</argument>
<summary>Close a hash handle</summary>
<prose>Close a hash handle when you have finished using it.</prose>
<related><dataref>HashHandle</dataref></related>
<related><functionref>finalHash</functionref></related>
<related><functionref>getHash</functionref></related>
<related><functionref>hashBinary</functionref></related>
<related><functionref>hashString</functionref></related>
<related><functionref>openHash</functionref></related>
<related><functionref>resetHash</functionref></related>"
public Void closeHash(HashHandle h)
{
    do_hashClose(h.ptr);
}

"<argument name='h'>The hash handle</argument>
<summary>Reset a hash handle</summary>
<prose>Reset a hash handle. If you are using the same hash algorithm on several pieces of data, it is more efficient to reset it after each use, rather than closing and re-opening.</prose>
<related><dataref>HashHandle</dataref></related>
<related><functionref>closeHash</functionref></related>
<related><functionref>finalHash</functionref></related>
<related><functionref>getHash</functionref></related>
<related><functionref>hashBinary</functionref></related>
<related><functionref>hashString</functionref></related>
<related><functionref>openHash</functionref></related>"
public Void resetHash(HashHandle h)
{
    do_hashReset(h.ptr);
}

"<argument name='h'>A hash handle</argument>
<argument name='dat'>A block of binary data</argument>
<summary>Hash binary data</summary>
<prose>Hash a block of binary data.</prose>
<related><dataref>HashHandle</dataref></related>
<related><functionref>closeHash</functionref></related>
<related><functionref>finalHash</functionref></related>
<related><functionref>getHash</functionref></related>
<related><functionref>hashString</functionref></related>
<related><functionref>openHash</functionref></related>
<related><functionref>resetHash</functionref></related>"
public Void hashBinary(HashHandle h, Binary dat)
{
    do_hashWrite(h.ptr, blockData(dat), blockSize(dat));
}

"<argument name='h'>A hash handle</argument>
<argument name='str'>A String</argument>
<summary>Hash string data</summary>
<prose>Hash a String.</prose>
<related><dataref>HashHandle</dataref></related>
<related><functionref>closeHash</functionref></related>
<related><functionref>finalHash</functionref></related>
<related><functionref>getHash</functionref></related>
<related><functionref>hashBinary</functionref></related>
<related><functionref>openHash</functionref></related>
<related><functionref>resetHash</functionref></related>"
public Void hashString(HashHandle h, String str)
{
    block = createBlock(byteLength(str)+1);
    pokeString(block,0,str);
    do_hashWrite(h.ptr, blockData(block), blockSize(block));
}

"<argument name='h'>A hash handle</argument>
<summary>Finalise the hash handle</summary>
<prose>Finalise the hash handle. This is not usually necessary as calling <functionref>getHash</functionref> implicitly finalises the handle. Once a handle is finalised, no further <functionref>hashString</functionref> or <functionref>hashBinary</functionref> operations have any effect until <functionref>resetHash</functionref> is used.</prose>
<related><dataref>HashHandle</dataref></related>
<related><functionref>closeHash</functionref></related>
<related><functionref>getHash</functionref></related>
<related><functionref>hashBinary</functionref></related>
<related><functionref>hashString</functionref></related>
<related><functionref>openHash</functionref></related>
<related><functionref>resetHash</functionref></related>"
public Void finalHash(HashHandle h)
{
    do_hashFinal(h.ptr);
}

"<argument name='h'>A hash handle</argument>
<summary>Get the hash result</summary>
<prose>Get the hash result, as a block of binary data.</prose>
<related><dataref>HashHandle</dataref></related>
<related><functionref>closeHash</functionref></related>
<related><functionref>getHash</functionref></related>
<related><functionref>hashBinary</functionref></related>
<related><functionref>hashString</functionref></related>
<related><functionref>openHash</functionref></related>
<related><functionref>resetHash</functionref></related>"
public Binary getHash(HashHandle h)
{
    size = 0;
    dat = do_hashGet(h.ptr, size);
    return createInitialisedBlock(dat,size);
}