File: Gcrypt.k

package info (click to toggle)
kaya 0.2.0-6
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 3,012 kB
  • ctags: 1,307
  • sloc: cpp: 6,691; haskell: 4,833; sh: 2,868; yacc: 768; makefile: 700; perl: 87
file content (179 lines) | stat: -rw-r--r-- 4,417 bytes parent folder | download
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
/** -*-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.
*/

module Gcrypt;

import Prelude;
import Binary;

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

"Available symmetric ciphers"
public data Cipher 
            = Idea | TripleDES | Cast5 | Blowfish | AES128 | AES192
            | AES256 | Twofish | Twofish128 | Arcfour | DES;

"Cipher modes"
public data CipherMode = ECB | CFB | CBC | Stream | OFB | CTR;

"Hash algorithms"
public data Hash = SHA1 | RMD160 | MD5 | MD4 | Tiger | SHA256 | CRC32;

abstract data CipherHandle(Ptr ptr);
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;
}

public CipherHandle openCipher(Cipher algo, CipherMode mode, Int flags = 0)
{
    return CipherHandle(do_cipherOpen(algo,mode,flags));
}

public Void closeCipher(CipherHandle h)
{
    do_cipherClose(h.ptr);
}

public Void setCipherKey(CipherHandle h, Key key)
{
    // TODO: Check that key length is right. If not, pad/chop
    do_setkey(h.ptr,key);
}

public Void setCipherIVec(CipherHandle h, IVec key)
{
    // TODO: Check that ivec length is right. If not, pad/chop
    do_setivec(h.ptr,key);
}

public [Int] appKey()
{
    return do_appKey();
}

public [Int] appIVec()
{
    return do_appIVec();
}

"Get the required key size for a given cipher."
public Int cipherKeySize(Cipher c) {
    return do_cipherKeySize(algo(c));
}

"Get the required block length for a given cipher."
public Int cipherBlockLength(Cipher c) {
    return do_cipherBlockLength(algo(c));
}

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);
}

public Binary decrypt(CipherHandle h, Binary dat)
{
    outlen = 0;
    ptr = do_decrypt(h.ptr, blockData(dat), blockSize(dat), outlen);
    return createInitialisedBlock(ptr, outlen);
}

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);
}

public String decryptString(CipherHandle h, String x)
{
    block = Binary::base64Decode(x);
    decryptblock = decrypt(h,block);
    return peekString(decryptblock,0);
}

public HashHandle openHash(Hash algo, Int flags = 0)
{
    return HashHandle(do_hashOpen(algo,flags));
}

public Void closeHash(HashHandle h)
{
    do_hashClose(h.ptr);
}

public Void resetHash(HashHandle h)
{
    do_hashReset(h.ptr);
}

public Void hashBinary(HashHandle h, Binary dat)
{
    do_hashWrite(h.ptr, blockData(dat), blockSize(dat));
}

public Void hashString(HashHandle h, String str)
{
    block = createBlock(byteLength(str)+1);
    pokeString(block,0,str);
    do_hashWrite(h.ptr, blockData(block), blockSize(block));
}

public Void finalHash(HashHandle h)
{
    do_hashFinal(h.ptr);
}

public Binary getHash(HashHandle h)
{
    size = 0;
    dat = do_hashGet(h.ptr, size);
    return createInitialisedBlock(dat,size);
}