commoncrypto_sys/lib.rs
1// Copyright (c) 2016 Mark Lee
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20
21//! Low-level bindings to OSX/macOS/iOS's `CommonCrypto` library.
22
23#![warn(missing_docs)]
24
25extern crate libc;
26
27use libc::{c_int, c_uint};
28
29/// Total number of operations.
30const MD5_CBLOCK: usize = 64;
31/// Number of operations per round.
32const MD5_LBLOCK: usize = MD5_CBLOCK / 4;
33/// Number of bytes for an MD5 hash.
34pub const MD5_DIGEST_LENGTH: usize = 16;
35
36const SHA_LBLOCK: usize = 16;
37/// Number of bytes for an SHA1 hash.
38pub const SHA1_DIGEST_LENGTH: usize = 20;
39/// Number of bytes for an SHA256 hash.
40pub const SHA256_DIGEST_LENGTH: usize = 32;
41/// Number of bytes for an SHA384 hash.
42pub const SHA384_DIGEST_LENGTH: usize = 48;
43/// Number of bytes for an SHA512 hash.
44pub const SHA512_DIGEST_LENGTH: usize = 64;
45
46/// Struct used to generate MD5 hashes.
47#[allow(non_camel_case_types, non_snake_case)]
48#[derive(Clone, Debug, Default, PartialEq)]
49#[repr(C)]
50pub struct CC_MD5_CTX {
51 A: c_uint,
52 B: c_uint,
53 C: c_uint,
54 D: c_uint,
55 Nl: c_uint,
56 Nh: c_uint,
57 data: [c_uint; MD5_LBLOCK],
58 num: c_uint,
59}
60
61/// Struct used to generate SHA1 hashes.
62#[allow(non_camel_case_types, non_snake_case)]
63#[derive(Clone, Debug, Default, PartialEq)]
64#[repr(C)]
65pub struct CC_SHA_CTX {
66 h0: c_uint,
67 h1: c_uint,
68 h2: c_uint,
69 h3: c_uint,
70 h4: c_uint,
71 Nl: c_uint,
72 Nh: c_uint,
73 data: [c_uint; SHA_LBLOCK],
74 num: c_uint,
75}
76
77macro_rules! cc_sha2_struct {
78 ($ctx_name: ident, $ty: ty) => {
79 /// Struct used to generate SHA2 hashes with the given bits.
80 #[allow(non_camel_case_types, non_snake_case)]
81 #[derive(Clone, Debug, Default, PartialEq)]
82 #[repr(C)]
83 pub struct $ctx_name {
84 count: [$ty; 2],
85 hash: [$ty; 8],
86 wbuf: [$ty; 16],
87 }
88 }
89}
90
91cc_sha2_struct!(CC_SHA256_CTX, u32);
92cc_sha2_struct!(CC_SHA512_CTX, u64);
93
94/// Digest algorithm used in `CCDigest*()` functions.
95#[repr(C)]
96pub enum CCDigestAlgorithm {
97 /// No digest algorithm
98 kCCDigestNone = 0,
99 /// MD2
100 kCCDigestMD2 = 1,
101 /// MD4
102 kCCDigestMD4 = 2,
103 /// MD5
104 kCCDigestMD5 = 3,
105 /// RIPEMD-128
106 kCCDigestRMD128 = 4,
107 /// RIPEMD-160
108 kCCDigestRMD160 = 5,
109 /// RIPEMD-256
110 kCCDigestRMD256 = 6,
111 /// RIPEMD-320
112 kCCDigestRMD320 = 7,
113 /// SHA1
114 kCCDigestSHA1 = 8,
115 /// SHA224
116 kCCDigestSHA224 = 9,
117 /// SHA256
118 kCCDigestSHA256 = 10,
119 /// SHA384
120 kCCDigestSHA384 = 11,
121 /// SHA512
122 kCCDigestSHA512 = 12,
123 /// Skein, 128 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
124 kCCDigestSkein128 = 13,
125 /// Skein, 160 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
126 kCCDigestSkein160 = 14,
127 /// Skein, 224 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
128 kCCDigestSkein224 = 16,
129 /// Skein, 256 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
130 kCCDigestSkein256 = 17,
131 /// Skein, 384 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
132 kCCDigestSkein384 = 18,
133 /// Skein, 512 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
134 kCCDigestSkein512 = 19,
135}
136
137const CC_DIGEST_SIZE: usize = 1032;
138
139/// Context used in `CCDigest*()` functions.
140#[allow(non_camel_case_types, non_snake_case)]
141#[repr(C)]
142pub struct CCDigestCtx {
143 context: [u8; CC_DIGEST_SIZE],
144}
145
146/// Algorithm for use with `CCKeyDerivationPBKDF()`.
147#[repr(C)]
148pub enum CCPBKDFAlgorithm {
149 /// PBKDF2
150 kCCPBKDF2 = 2,
151}
152
153/// Pseudo-random algorithm to use with `CCKeyDerivationPBKDF()`.
154#[repr(C)]
155pub enum CCPseudoRandomAlgorithm {
156 /// SHA-1
157 kCCPRFHmacAlgSHA1 = 1,
158 /// SHA-224
159 kCCPRFHmacAlgSHA224 = 2,
160 /// SHA-256
161 kCCPRFHmacAlgSHA256 = 3,
162 /// SHA-384
163 kCCPRFHmacAlgSHA384 = 4,
164 /// SHA-512
165 kCCPRFHmacAlgSHA512 = 5,
166}
167
168extern "C" {
169 /// Initializes MD5 hasher. See `man 3cc CC_MD5` for details.
170 pub fn CC_MD5_Init(ctx: *mut CC_MD5_CTX) -> c_int;
171 /// Appends data to be hashed. See `man 3cc CC_MD5` for details.
172 pub fn CC_MD5_Update(ctx: *mut CC_MD5_CTX, data: *const u8, n: usize) -> c_int;
173 /// Generates MD5 hash. See `man 3cc CC_MD5` for details.
174 pub fn CC_MD5_Final(md: *mut u8, ctx: *mut CC_MD5_CTX) -> c_int;
175 /// Initializes SHA1 hasher. See `man 3cc CC_SHA` for details.
176 pub fn CC_SHA1_Init(ctx: *mut CC_SHA_CTX) -> c_int;
177 /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
178 pub fn CC_SHA1_Update(ctx: *mut CC_SHA_CTX, data: *const u8, n: usize) -> c_int;
179 /// Generates SHA1 hash. See `man 3cc CC_SHA` for details.
180 pub fn CC_SHA1_Final(md: *mut u8, ctx: *mut CC_SHA_CTX) -> c_int;
181 /// Initializes SHA256 hasher. See `man 3cc CC_SHA` for details.
182 pub fn CC_SHA256_Init(ctx: *mut CC_SHA256_CTX) -> c_int;
183 /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
184 pub fn CC_SHA256_Update(ctx: *mut CC_SHA256_CTX, data: *const u8, n: usize) -> c_int;
185 /// Generates SHA256 hash. See `man 3cc CC_SHA` for details.
186 pub fn CC_SHA256_Final(md: *mut u8, ctx: *mut CC_SHA256_CTX) -> c_int;
187 /// Initializes SHA384 hasher. See `man 3cc CC_SHA` for details.
188 pub fn CC_SHA384_Init(ctx: *mut CC_SHA512_CTX) -> c_int;
189 /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
190 pub fn CC_SHA384_Update(ctx: *mut CC_SHA512_CTX, data: *const u8, n: usize) -> c_int;
191 /// Generates SHA384 hash. See `man 3cc CC_SHA` for details.
192 pub fn CC_SHA384_Final(md: *mut u8, ctx: *mut CC_SHA512_CTX) -> c_int;
193 /// Initializes SHA512 hasher. See `man 3cc CC_SHA` for details.
194 pub fn CC_SHA512_Init(ctx: *mut CC_SHA512_CTX) -> c_int;
195 /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
196 pub fn CC_SHA512_Update(ctx: *mut CC_SHA512_CTX, data: *const u8, n: usize) -> c_int;
197 /// Generates SHA512 hash. See `man 3cc CC_SHA` for details.
198 pub fn CC_SHA512_Final(md: *mut u8, ctx: *mut CC_SHA512_CTX) -> c_int;
199 /// Generic digest hasher.
200 pub fn CCDigest(algorithm: CCDigestAlgorithm,
201 data: *const u8,
202 length: usize,
203 output: *mut u8)
204 -> c_int;
205 /// Allocate and initialize a `CCDigestCtx` for a digest.
206 pub fn CCDigestCreate(algorithm: CCDigestAlgorithm) -> *mut CCDigestCtx;
207 /// Continue to digest data. Returns `0` on success.
208 pub fn CCDigestUpdate(ctx: *mut CCDigestCtx, data: *const u8, length: usize) -> c_int;
209 /// Conclude digest operations and produce the digest output. Returns `0` on success.
210 pub fn CCDigestFinal(ctx: *mut CCDigestCtx, output: *mut u8) -> c_int;
211 /// Clear and free a `CCDigestCtx`.
212 pub fn CCDigestDestroy(ctx: *mut CCDigestCtx);
213 /// Clear and re-initialize a `CCDigestCtx` for the same algorithm.
214 pub fn CCDigestReset(ctx: *mut CCDigestCtx);
215 /// Produce the digest output result for the bytes currently processed. Returns `0` on success.
216 pub fn CCDigestGetDigest(ctx: *mut CCDigestCtx, output: *mut u8) -> c_int;
217 /// Provides the block size of the digest algorithm. Returns `0` on failure.
218 pub fn CCDigestGetBlockSize(algorithm: CCDigestAlgorithm) -> usize;
219 /// Provides the digest output size of the digest algorithm. Returns `0` on failure.
220 pub fn CCDigestGetOutputSize(algorithm: CCDigestAlgorithm) -> usize;
221 /// Provides the block size of the digest algorithm. Returns `0` on failure.
222 pub fn CCDigestGetBlockSizeFromRef(ctx: *mut CCDigestCtx) -> usize;
223 /// Provides the digest output size of the digest algorithm. Returns `0` on failure.
224 pub fn CCDigestGetOutputSizeFromRef(ctx: *mut CCDigestCtx) -> usize;
225
226 /// Derive a key from a user-supplied password via PBKDF2.
227 pub fn CCKeyDerivationPBKDF(algorithm: CCPBKDFAlgorithm,
228 password: *const u8,
229 passwordLen: usize,
230 salt: *const u8,
231 saltLen: usize,
232 prf: CCPseudoRandomAlgorithm,
233 rounds: u32,
234 derivedKey: *mut u8,
235 derivedKeyLen: usize)
236 -> c_int;
237}