From f8512d7d5e17d2a59cfdd18dff0817d75e4b4c92 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 11 Mar 2013 20:49:04 +0100 Subject: [PATCH] Add RC4 and AES-128 support to Cryptor --- .gitignore | 1 + README.md | 3 ++- crypto.rc | 9 ++++++--- rand.rs | 3 ++- symm.rs | 36 ++++++++++++++++++++++++++++++++++-- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index cd49243d..ecfc5572 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.sw[po] libcrypto*.dylib +libcrypto*.so *.dSYM/ crypto diff --git a/README.md b/README.md index 82a1c526..4554176d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ libcrypto. Currently provided: * SHA-1 * SHA-2 (224, 256, 384, 512) * Symmetric crypto (symm.rs) - * AES in ECB or CBC mode, all key lengths + * AES-128 or AES-256 in ECB or CBC mode + * RC4-128 * Keypair generation (pkey.rs) * RSA, all key lengths * Asymmetric encryption (pkey.rs) diff --git a/crypto.rc b/crypto.rc index 0f33533f..eeccd14f 100644 --- a/crypto.rc +++ b/crypto.rc @@ -1,5 +1,6 @@ /* * Copyright 2011 Google Inc. + * 2013 Jack Lloyd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +16,16 @@ */ #[link(name = "crypto", - vers = "0.2", + vers = "0.3", uuid = "38297409-b4c2-4499-8131-a99a7e44dad3")]; #[crate_type = "lib"]; extern mod std; // FIXME https://github.com/mozilla/rust/issues/1127 +pub mod hex; pub mod hash; -pub mod pkey; -pub mod symm; +pub mod hmac; pub mod pkcs5; +pub mod pkey; pub mod rand; +pub mod symm; diff --git a/rand.rs b/rand.rs index c6e0c4a0..72acdd19 100644 --- a/rand.rs +++ b/rand.rs @@ -23,6 +23,7 @@ pub fn rand_bytes(len: uint) -> ~[u8] { mod tests { #[test] fn test_rand_bytes() { - let _bytes = rand_bytes(5u); + let bytes = rand_bytes(32u); + io::println(fmt!("%?", bytes)); } } diff --git a/symm.rs b/symm.rs index b0b92638..030802f6 100644 --- a/symm.rs +++ b/symm.rs @@ -23,6 +23,8 @@ extern mod libcrypto { fn EVP_aes_256_ecb() -> EVP_CIPHER; fn EVP_aes_256_cbc() -> EVP_CIPHER; + fn EVP_rc4() -> EVP_CIPHER; + fn EVP_CipherInit(ctx: EVP_CIPHER_CTX, evp: EVP_CIPHER, key: *u8, iv: *u8, mode: c_int); fn EVP_CipherUpdate(ctx: EVP_CIPHER_CTX, outbuf: *mut u8, @@ -37,14 +39,24 @@ pub enum Mode { #[allow(non_camel_case_types)] pub enum Type { + AES_128_ECB, + AES_128_CBC, + AES_256_ECB, AES_256_CBC, + + RC4_128, } fn evpc(t: Type) -> (EVP_CIPHER, uint, uint) { match t { + AES_128_ECB => (libcrypto::EVP_aes_128_ecb(), 16u, 16u), + AES_128_CBC => (libcrypto::EVP_aes_128_cbc(), 16u, 16u), + AES_256_ECB => (libcrypto::EVP_aes_256_ecb(), 32u, 16u), AES_256_CBC => (libcrypto::EVP_aes_256_cbc(), 32u, 16u), + + RC4_128 => (libcrypto::EVP_rc4(), 16u, 0u), } } @@ -68,8 +80,10 @@ pub impl Crypter { * data encrypted must be a multiple of block size. */ fn pad(padding: bool) { - let v = if padding { 1 } else { 0} as c_int; - libcrypto::EVP_CIPHER_CTX_set_padding(self.ctx, v); + if self.blocksize > 0 { + let v = if padding { 1 } else { 0 } as c_int; + libcrypto::EVP_CIPHER_CTX_set_padding(self.ctx, v); + } } /** @@ -188,4 +202,22 @@ mod tests { let p1 = c.update(r0) + c.final(); assert(p1 == p0); } + + #[test] + pub fn test_rc4() { + use hex::FromHex; + + let pt = ~"0000000000000000000000000000000000000000000000000000000000000000000000000000"; + let ct = ~"A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4"; + let key = ~"97CD440324DA5FD1F7955C1C13B6B466"; + let iv = ~""; + + let cipher = Crypter(RC4_128); + cipher.init(Encrypt, key.from_hex(), iv.from_hex()); + + let computed = cipher.update(pt.from_hex()); + + assert computed == ct.from_hex(); + } + }