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