cryptoxide/
mac.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7/*!
8 * The mac module defines the Message Authentication Code (`Mac`) trait.
9 */
10
11use crate::constant_time::CtEqual;
12use alloc::vec::Vec;
13
14/**
15 * The `Mac` trait defines methods for a Message Authentication function.
16 */
17pub trait Mac {
18    /**
19     * Process input data.
20     *
21     * # Arguments
22     * * data - The input data to process.
23     *
24     */
25    fn input(&mut self, data: &[u8]);
26
27    /**
28     * Reset the Mac state to begin processing another input stream.
29     */
30    fn reset(&mut self);
31
32    /**
33     * Obtain the result of a Mac computation as a `MacResult`.
34     */
35    fn result(&mut self) -> MacResult;
36
37    /**
38     * Obtain the result of a Mac computation as [u8]. This method should be used very carefully
39     * since incorrect use of the Mac code could result in permitting a timing attack which defeats
40     * the security provided by a Mac function.
41     */
42    fn raw_result(&mut self, output: &mut [u8]);
43
44    /**
45     * Get the size of the Mac code, in bytes.
46     */
47    fn output_bytes(&self) -> usize;
48}
49
50/**
51 * A `MacResult` wraps a Mac code and provides a safe Eq implementation that runs in fixed time.
52 */
53pub struct MacResult {
54    code: Vec<u8>,
55}
56
57impl MacResult {
58    /**
59     * Create a new `MacResult`.
60     */
61    pub fn new(code: &[u8]) -> MacResult {
62        MacResult {
63            code: code.to_vec(),
64        }
65    }
66
67    /**
68     * Create a new `MacResult` taking ownership of the specified code value.
69     */
70    pub fn new_from_owned(code: Vec<u8>) -> MacResult {
71        MacResult { code: code }
72    }
73
74    /**
75     * Get the code value. Be very careful using this method, since incorrect use of the code value
76     * may permit timing attacks which defeat the security provided by the Mac function.
77     */
78    pub fn code(&self) -> &[u8] {
79        &self.code[..]
80    }
81}
82
83impl PartialEq for MacResult {
84    fn eq(&self, x: &MacResult) -> bool {
85        let lhs = self.code();
86        let rhs = x.code();
87        // it's a user error to compare two mac results from two different mac
88        if lhs.len() == rhs.len() {
89            CtEqual::ct_eq(lhs, rhs).into()
90        } else {
91            false
92        }
93    }
94}
95
96impl Eq for MacResult {}