X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Frc5.c;h=290d311089e27306fdc4a0b4c2c2cfc76dd9b2ac;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=c0db8e950cbc57218ce3a888f5852fefa6d1908c;hpb=62f89b2886bbe9df82d9b2fdabfe707509d9e0fc;p=silc.git diff --git a/lib/silccrypt/rc5.c b/lib/silccrypt/rc5.c index c0db8e95..290d3110 100644 --- a/lib/silccrypt/rc5.c +++ b/lib/silccrypt/rc5.c @@ -30,17 +30,98 @@ */ /* - * Based on RC5 reference code and on description of Bruce Schneier's + * Based on RC5 reference code and on description of Bruce Schneier's * Applied Cryptography. * - * This implementation has a word size of 32 bits, a rounds of 16 and + * This implementation has a word size of 32 bits, a rounds of 16 and * variable key length from 128 and 192 up to 256 bits. * */ -#include "silcincludes.h" +#include "silc.h" +#include "rc5_internal.h" #include "rc5.h" +/* + * SILC Crypto API for RC5 + */ + +/* Sets the key for the cipher. */ + +SILC_CIPHER_API_SET_KEY(rc5_cbc) +{ + SilcUInt32 k[8]; + + SILC_GET_WORD_KEY(key, k, keylen); + rc5_set_key((RC5Context *)context, k, keylen); + + return TRUE; +} + +/* Sets IV for the cipher. */ + +SILC_CIPHER_API_SET_IV(rc5_cbc) +{ + +} + +/* Returns the size of the cipher context. */ + +SILC_CIPHER_API_CONTEXT_LEN(rc5_cbc) +{ + return sizeof(RC5Context); +} + +/* Encrypts with the cipher in CBC mode. Source and destination buffers + maybe one and same. */ + +SILC_CIPHER_API_ENCRYPT(rc5_cbc) +{ + SilcUInt32 tiv[4]; + int i; + + SILC_CBC_GET_IV(tiv, iv); + + SILC_CBC_ENC_PRE(tiv, src); + rc5_encrypt((RC5Context *)context, tiv, tiv); + SILC_CBC_ENC_POST(tiv, dst, src); + + for (i = 16; i < len; i += 16) { + SILC_CBC_ENC_PRE(tiv, src); + rc5_encrypt((RC5Context *)context, tiv, tiv); + SILC_CBC_ENC_POST(tiv, dst, src); + } + + SILC_CBC_PUT_IV(tiv, iv); + + return TRUE; +} + +/* Decrypts with the cipher in CBC mode. Source and destination buffers + maybe one and same. */ + +SILC_CIPHER_API_DECRYPT(rc5_cbc) +{ + SilcUInt32 tmp[4], tmp2[4], tiv[4]; + int i; + + SILC_CBC_GET_IV(tiv, iv); + + SILC_CBC_DEC_PRE(tmp, src); + rc5_decrypt((RC5Context *)context, tmp, tmp2); + SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv); + + for (i = 16; i < len; i += 16) { + SILC_CBC_DEC_PRE(tmp, src); + rc5_decrypt((RC5Context *)context, tmp, tmp2); + SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv); + } + + SILC_CBC_PUT_IV(tiv, iv); + + return TRUE; +} + /* RC5 encryption */ #define RC5E(i, A, B) \ A = A ^ B; \ @@ -57,17 +138,14 @@ /* Sets RC5 key */ -int rc5_set_key(RC5Context *ctx, char *key, int key_len) +int rc5_set_key(RC5Context *ctx, const SilcUInt32 in_key[], int key_len) { - u32 *in_key = (u32 *)key; u32 i, j, k, A, B, L[c]; u32 *out_key = ctx->out_key; if (key_len < b || key_len > (2 * b)) return -1; - // key_len *= 8; - /* init L */ for (i = 0; i < key_len / w; i++) L[i] = in_key[i]; @@ -127,9 +205,9 @@ int rc5_decrypt(RC5Context *ctx, u32 *in, u32 *out) A = in[0]; B = in[1]; - RC5D(32, A, B); RC5D(30, A, B); - RC5D(28, A, B); RC5D(26, A, B); - RC5D(24, A, B); RC5D(22, A, B); + RC5D(32, A, B); RC5D(30, A, B); + RC5D(28, A, B); RC5D(26, A, B); + RC5D(24, A, B); RC5D(22, A, B); RC5D(20, A, B); RC5D(18, A, B); RC5D(16, A, B); RC5D(14, A, B); RC5D(12, A, B); RC5D(10, A, B); @@ -140,4 +218,4 @@ int rc5_decrypt(RC5Context *ctx, u32 *in, u32 *out) out[1] = B - S[1]; return 0; -} +}