Loading Makefile 0 → 100644 +7 −0 Original line number Diff line number Diff line crypto: crypto.rc $(wildcard *.rs) rustc crypto.rc rustc --test crypto.rc clean: rm -f crypto libcrypto-*.so hex.rs 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ extern mod std; pub trait ToHex { pure fn to_hex() -> ~str; } impl &[u8]: ToHex { pure fn to_hex() -> ~str { let chars = str::chars(~"0123456789ABCDEF"); let mut s = ~""; for uint::range(0, self.len()) |i| { let x = self[i]; let xhi = (x >> 4) & 0x0F; let xlo = (x ) & 0x0F; unsafe { str::push_char(&mut s, chars[xhi]); str::push_char(&mut s, chars[xlo]); } } s } } pub trait FromHex { pure fn from_hex() -> ~[u8]; } impl &str: FromHex { pure fn from_hex() -> ~[u8] { let mut vec = vec::with_capacity(self.len() / 2); for str::each_chari(self) |i,c| { let nibble = if c >= '0' && c <= '9' { (c as u8) - 0x30 } else if c >= 'a' && c <= 'f' { (c as u8) - (0x61 - 10) } else if c >= 'A' && c <= 'F' { (c as u8) - (0x41 - 10) } else { fail ~"bad hex character"; }; if i % 2 == 0 { unsafe { vec::push(&mut vec, nibble << 4); } } else { vec[i/2] |= nibble; } } vec } } #[cfg(test)] mod tests { #[test] pub fn test() { assert [05u8, 0xffu8, 0x00u8, 0x59u8].to_hex() == ~"05FF0059"; assert "00FFA9D1F5".from_hex() == ~[0, 0xff, 0xa9, 0xd1, 0xf5]; assert "00FFA9D1F5".from_hex().to_hex() == ~"00FFA9D1F5"; } } No newline at end of file hmac.rs 0 → 100644 +92 −0 Original line number Diff line number Diff line /* * Copyright 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ use hash::*; #[allow(non_camel_case_types)] struct HMAC_CTX { mut md: EVP_MD, mut md_ctx: EVP_MD_CTX, mut i_ctx: EVP_MD_CTX, mut o_ctx: EVP_MD_CTX, mut key_length: libc::c_uint, mut key: [libc::c_uchar * 128] } #[link_name = "crypto"] #[abi = "cdecl"] extern mod libcrypto { fn HMAC_CTX_init(ctx: *mut HMAC_CTX, key: *u8, keylen: libc::c_int, md: EVP_MD); fn HMAC_Update(ctx: *mut HMAC_CTX, input: *u8, len: libc::c_uint); fn HMAC_Final(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut libc::c_uint); } pub struct HMAC { priv mut ctx: HMAC_CTX, priv len: uint, } pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { unsafe { let (evp, mdlen) = evpmd(ht); let mut ctx : HMAC_CTX = HMAC_CTX { mut md: ptr::null(), mut md_ctx: ptr::null(), mut i_ctx: ptr::null(), mut o_ctx: ptr::null(), mut key_length: 0, mut key: [0u8, .. 128] }; libcrypto::HMAC_CTX_init(&mut ctx, vec::raw::to_ptr(key), key.len() as libc::c_int, evp); HMAC { ctx: ctx, len: mdlen } } } pub impl HMAC { fn update(data: &[u8]) unsafe { do vec::as_imm_buf(data) |pdata, len| { libcrypto::HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) } } fn final() -> ~[u8] unsafe { let mut res = vec::from_elem(self.len, 0u8); let mut outlen: libc::c_uint = 0; do vec::as_mut_buf(res) |pres, _len| { libcrypto::HMAC_Final(&mut self.ctx, pres, &mut outlen); assert self.len == outlen as uint } res } } fn main() { let h = HMAC(SHA512, ~[00u8]); h.update(~[00u8]); io::println(fmt!("%?", h.final())) } Loading
Makefile 0 → 100644 +7 −0 Original line number Diff line number Diff line crypto: crypto.rc $(wildcard *.rs) rustc crypto.rc rustc --test crypto.rc clean: rm -f crypto libcrypto-*.so
hex.rs 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ extern mod std; pub trait ToHex { pure fn to_hex() -> ~str; } impl &[u8]: ToHex { pure fn to_hex() -> ~str { let chars = str::chars(~"0123456789ABCDEF"); let mut s = ~""; for uint::range(0, self.len()) |i| { let x = self[i]; let xhi = (x >> 4) & 0x0F; let xlo = (x ) & 0x0F; unsafe { str::push_char(&mut s, chars[xhi]); str::push_char(&mut s, chars[xlo]); } } s } } pub trait FromHex { pure fn from_hex() -> ~[u8]; } impl &str: FromHex { pure fn from_hex() -> ~[u8] { let mut vec = vec::with_capacity(self.len() / 2); for str::each_chari(self) |i,c| { let nibble = if c >= '0' && c <= '9' { (c as u8) - 0x30 } else if c >= 'a' && c <= 'f' { (c as u8) - (0x61 - 10) } else if c >= 'A' && c <= 'F' { (c as u8) - (0x41 - 10) } else { fail ~"bad hex character"; }; if i % 2 == 0 { unsafe { vec::push(&mut vec, nibble << 4); } } else { vec[i/2] |= nibble; } } vec } } #[cfg(test)] mod tests { #[test] pub fn test() { assert [05u8, 0xffu8, 0x00u8, 0x59u8].to_hex() == ~"05FF0059"; assert "00FFA9D1F5".from_hex() == ~[0, 0xff, 0xa9, 0xd1, 0xf5]; assert "00FFA9D1F5".from_hex().to_hex() == ~"00FFA9D1F5"; } } No newline at end of file
hmac.rs 0 → 100644 +92 −0 Original line number Diff line number Diff line /* * Copyright 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ use hash::*; #[allow(non_camel_case_types)] struct HMAC_CTX { mut md: EVP_MD, mut md_ctx: EVP_MD_CTX, mut i_ctx: EVP_MD_CTX, mut o_ctx: EVP_MD_CTX, mut key_length: libc::c_uint, mut key: [libc::c_uchar * 128] } #[link_name = "crypto"] #[abi = "cdecl"] extern mod libcrypto { fn HMAC_CTX_init(ctx: *mut HMAC_CTX, key: *u8, keylen: libc::c_int, md: EVP_MD); fn HMAC_Update(ctx: *mut HMAC_CTX, input: *u8, len: libc::c_uint); fn HMAC_Final(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut libc::c_uint); } pub struct HMAC { priv mut ctx: HMAC_CTX, priv len: uint, } pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { unsafe { let (evp, mdlen) = evpmd(ht); let mut ctx : HMAC_CTX = HMAC_CTX { mut md: ptr::null(), mut md_ctx: ptr::null(), mut i_ctx: ptr::null(), mut o_ctx: ptr::null(), mut key_length: 0, mut key: [0u8, .. 128] }; libcrypto::HMAC_CTX_init(&mut ctx, vec::raw::to_ptr(key), key.len() as libc::c_int, evp); HMAC { ctx: ctx, len: mdlen } } } pub impl HMAC { fn update(data: &[u8]) unsafe { do vec::as_imm_buf(data) |pdata, len| { libcrypto::HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) } } fn final() -> ~[u8] unsafe { let mut res = vec::from_elem(self.len, 0u8); let mut outlen: libc::c_uint = 0; do vec::as_mut_buf(res) |pres, _len| { libcrypto::HMAC_Final(&mut self.ctx, pres, &mut outlen); assert self.len == outlen as uint } res } } fn main() { let h = HMAC(SHA512, ~[00u8]); h.update(~[00u8]); io::println(fmt!("%?", h.final())) }