Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dnaq committed Dec 5, 2013
0 parents commit 59bc04e
Show file tree
Hide file tree
Showing 15 changed files with 1,776 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*~
*.sw*
*.o
/doc
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Daniel Ashhami (dnaq)

Author of sodium: Frank Denis (jedisct1)
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2013 Daniel Ashhami

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
170 changes: 170 additions & 0 deletions src/crypto/auth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*!
Secret-key authentication
# Security model
The `authenticate()` function, viewed as a function of the
message for a uniform random key, is designed to meet the standard
notion of unforgeability. This means that an attacker cannot find
authenticators for any messages not authenticated by the sender, even if
the attacker has adaptively influenced the messages authenticated by the
sender. For a formal definition see, e.g., Section 2.4 of Bellare,
Kilian, and Rogaway, "The security of the cipher block chaining message
authentication code," Journal of Computer and System Sciences 61 (2000),
362–399; http://www-cse.ucsd.edu/~mihir/papers/cbc.html.
NaCl does not make any promises regarding "strong" unforgeability;
perhaps one valid authenticator can be converted into another valid
authenticator for the same message. NaCl also does not make any promises
regarding "truncated unforgeability."
# Selected primitive
`authenticate()` is currently an implementation of
`HMAC-SHA-512-256`, i.e., the first 256 bits of `HMAC-SHA-512`.
`HMAC-SHA-512-256` is conjectured to meet the standard notion of
unforgeability.
*/
use std::libc::{c_ulonglong, c_int};
use std::vec::raw::{to_ptr, to_mut_ptr};
use randombytes::randombytes_into;
use crypto::verify::verify_32;

#[link(name = "sodium")]
#[link_args = "-lsodium"]
extern {
fn crypto_auth(a: *mut u8,
m: *u8,
mlen: c_ulonglong,
k: *u8) -> c_int;
fn crypto_auth_verify(a: *u8,
m: *u8,
mlen: c_ulonglong,
k: *u8) -> c_int;
}

pub static KEYBYTES: uint = 32;
pub static TAGBYTES: uint = 32;

/**
* Authentication `Key`
*
* When a `Key` goes out of scope its contents
* will be zeroed out
*/
pub struct Key([u8, ..KEYBYTES]);

impl Drop for Key {
fn drop(&mut self) {
for e in self.mut_iter() { *e = 0 }
}
}

/**
* Authentication `Tag`
*
* The tag implements the traits `TotalEq` and `Eq` using constant-time
* comparison functions. See `sodiumoxide::crypto::verify::verify_32`
*/
pub struct Tag([u8, ..TAGBYTES]);
impl TotalEq for Tag {
fn equals(&self, other: &Tag) -> bool {
verify_32(&**self, &**other)
}
}
impl Eq for Tag {
fn eq(&self, other: &Tag) -> bool {
verify_32(&**self, &**other)
}
}

/**
* `gen_key()` randomly generates a key for authentication
*
* THREAD SAFETY: `gen_key()` is thread-safe provided that you have
* called `sodiumoxide::init()` once before using any other function
* from sodiumoxide.
*/
pub fn gen_key() -> ~Key {
let mut key = ~Key([0, ..KEYBYTES]);
randombytes_into(**key);
key
}

/**
* `authenticate()` authenticates a message `m` using a secret key `k`.
* The function returns an authenticator tag.
*/
#[fixed_stack_segment]
pub fn authenticate(m: &[u8], k: &Key) -> ~Tag {
unsafe {
let mut tag = ~Tag([0, ..TAGBYTES]);
crypto_auth(to_mut_ptr(**tag), to_ptr(m), m.len() as c_ulonglong, to_ptr(**k));
tag
}
}

/**
* `verify()` returns `true` if `tag` is a correct authenticator of message `m`
* under a secret key `k`. Otherwise it returns false.
*/
#[fixed_stack_segment]
pub fn verify(tag: &Tag, m: &[u8], k: &Key) -> bool {
unsafe {
crypto_auth_verify(to_ptr(**tag),
to_ptr(m),
m.len() as c_ulonglong,
to_ptr(**k)) == 0
}
}

#[test]
fn test_auth_verify() {
use randombytes::randombytes;
for _ in range(0, 256) {
let k = gen_key();
let m = randombytes(1024);
let tag = authenticate(m, k);
assert!(verify(tag, m, k));
}
}

#[test]
fn test_auth_verify_tamper() {
use randombytes::randombytes;
for _ in range(0, 32) {
let k = gen_key();
let mut m = randombytes(1024);
let mut tag = authenticate(m, k);
for i in range(0, m.len()) {
m[i] ^= 0x20;
assert!(!verify(tag, m, k));
m[i] ^= 0x20;
}
for i in range(0, tag.len()) {
tag[i] ^= 0x20;
assert!(!verify(tag, m, k));
tag[i] ^= 0x20;
}
}
}

#[test]
fn test_vector_1() {
/* "Test Case 2" from RFC 4231 */
let key = Key([74, 101, 102, 101, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0, 0]);
let c = [0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20
,0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20
,0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68
,0x69, 0x6e, 0x67, 0x3f];

let a_expected = ~Tag([0x16,0x4b,0x7a,0x7b,0xfc,0xf8,0x19,0xe2
,0xe3,0x95,0xfb,0xe7,0x3b,0x56,0xe0,0xa3
,0x87,0xbd,0x64,0x22,0x2e,0x83,0x1f,0xd6
,0x10,0x27,0x0c,0xd7,0xea,0x25,0x05,0x54]);

let a = authenticate(c, &key);
assert!((**a) == (**a_expected));
}

Loading

0 comments on commit 59bc04e

Please sign in to comment.