mirror of
https://github.com/darlinghq/darling-corecrypto.git
synced 2024-11-23 12:19:44 +00:00
Use original corecrypto headers
We're fine license-wise, because these headers are APSL licensed and included in XNUx
This commit is contained in:
parent
3c805b7d3c
commit
1688b7f97e
@ -1,90 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lubos Dolezel
|
||||
* cc.h
|
||||
* corecrypto
|
||||
*
|
||||
* This file is part of Darling CoreCrypto.
|
||||
* Created on 12/16/2010
|
||||
*
|
||||
* Darling is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CC_H
|
||||
#define _CORECRYPTO_CC_H
|
||||
#ifndef _CORECRYPTO_CC_H_
|
||||
#define _CORECRYPTO_CC_H_
|
||||
|
||||
#include <corecrypto/cc_config.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define cc_aligned_struct(alignment) \
|
||||
typedef struct\
|
||||
{ \
|
||||
uint8_t dummy[alignment]; \
|
||||
} __attribute__((aligned(alignment)))
|
||||
|
||||
#define cc_ctx_n(type, size) ((sizeof(type) + size - 1) / sizeof(type))
|
||||
|
||||
#define cc_ctx_sizeof(type, size) sizeof(type[cc_ctx_n(type, size)])
|
||||
|
||||
#define cc_ctx_decl(type, size, name) type name[cc_ctx_n(type, size)]
|
||||
|
||||
inline void cc_zero(size_t size ,void* data)
|
||||
{
|
||||
memset(data, 0, size);
|
||||
}
|
||||
|
||||
void cc_clear(size_t len, void* dst);
|
||||
|
||||
inline void* cc_copy(size_t size, void* dst, const void* src)
|
||||
{
|
||||
return memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
inline void cc_xor(size_t size, void* result, const void* left, const void* right)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t* res8 = (uint8_t*) result;
|
||||
const uint8_t* l8 = (const uint8_t*) left;
|
||||
const uint8_t* r8 = (const uint8_t*) right;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
res8[i] = l8[i] ^ r8[i];
|
||||
}
|
||||
|
||||
// memcmp in const time
|
||||
int cc_cmp_safe(size_t num, const void* ptr1, const void* ptr2);
|
||||
|
||||
// return (s) ? a : b // in const time
|
||||
void* cc_muxp(int s, const void *a, const void *b);
|
||||
|
||||
#define CC_SWAP(a,b) {\
|
||||
__typeof__(a) tmp = a;\
|
||||
a = b;\
|
||||
b = tmp;\
|
||||
}
|
||||
|
||||
// Like the max macro, but params are evaluated only once
|
||||
#define CC_MAX(a, b) ({\
|
||||
__typeof__(a) ax = a;\
|
||||
__typeof__(b) bx = b;\
|
||||
ax > bx ? ax : bx;\
|
||||
})
|
||||
|
||||
// Like the min macro, but params are evaluated only once
|
||||
#define CC_MIN(a, b) ({\
|
||||
__typeof__(a) ax = a;\
|
||||
__typeof__(b) bx = b;\
|
||||
ax < bx ? ax : bx;\
|
||||
})
|
||||
|
||||
/* Manage asserts here because a few functions in header public files do use asserts */
|
||||
#define cc_assert(x) assert(x)
|
||||
#if CC_KERNEL
|
||||
#include <kern/assert.h>
|
||||
#elif CC_USE_S3
|
||||
#define assert(args) // No assert in S3
|
||||
#else
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
/* Declare a struct element with a guarenteed alignment of _alignment_.
|
||||
The resulting struct can be used to create arrays that are aligned by
|
||||
a certain amount. */
|
||||
#define cc_aligned_struct(_alignment_) \
|
||||
typedef struct { \
|
||||
uint8_t b[_alignment_]; \
|
||||
} CC_ALIGNED(_alignment_)
|
||||
|
||||
/* number of array elements used in a cc_ctx_decl */
|
||||
#define cc_ctx_n(_type_, _size_) ((_size_ + sizeof(_type_) - 1) / sizeof(_type_))
|
||||
|
||||
/* sizeof of a context declared with cc_ctx_decl */
|
||||
#define cc_ctx_sizeof(_type_, _size_) sizeof(_type_[cc_ctx_n(_type_, _size_)])
|
||||
|
||||
//- WARNING: The _MSC_VER version of cc_ctx_decl() is not compatible with the way *_decl macros are used in CommonCrypto, AppleKeyStore and SecurityFrameworks
|
||||
// to observe the incompatibilities and errors, use below definition. Corecrypto itself, accepts both deinitions
|
||||
// #define cc_ctx_decl(_type_, _size_, _name_) _type_ _name_ ## _array[cc_ctx_n(_type_, (_size_))]; _type_ *_name_ = _name_ ## _array
|
||||
//- Never use sizeof() operator for the variables declared with cc_ctx_decl(), because it is not be compatible with the _MSC_VER version of cc_ctx_decl().
|
||||
#if defined(_MSC_VER)
|
||||
#define UNIQUE_ARRAY(data_type, _var_, total_count) data_type* _var_ = (data_type*)_alloca(sizeof(data_type)*(total_count));
|
||||
#define cc_ctx_decl(_type_, _size_, _name_) UNIQUE_ARRAY(_type_, _name_,cc_ctx_n(_type_, (_size_)))
|
||||
#else
|
||||
#define cc_ctx_decl(_type_, _size_, _name_) _type_ _name_ [cc_ctx_n(_type_, _size_)]
|
||||
#endif
|
||||
|
||||
/* bzero is deprecated. memset is the way to go */
|
||||
/* FWIW, L4, HEXAGON and ARMCC even with gnu compatibility mode don't have bzero */
|
||||
#define cc_zero(_size_,_data_) memset((_data_),0 ,(_size_))
|
||||
|
||||
/* cc_clear:
|
||||
Set "len" bytes of memory to zero at address "dst".
|
||||
cc_clear has been developed so that it won't be optimized out.
|
||||
To be used to clear key buffers or sensitive data.
|
||||
*/
|
||||
CC_NONNULL2
|
||||
void cc_clear(size_t len, void *dst);
|
||||
|
||||
#define cc_copy(_size_, _dst_, _src_) memcpy(_dst_, _src_, _size_)
|
||||
|
||||
CC_INLINE CC_NONNULL2 CC_NONNULL3 CC_NONNULL4
|
||||
void cc_xor(size_t size, void *r, const void *s, const void *t) {
|
||||
uint8_t *_r=(uint8_t *)r;
|
||||
const uint8_t *_s=(const uint8_t *)s;
|
||||
const uint8_t *_t=(const uint8_t *)t;
|
||||
while (size--) {
|
||||
_r[size] = _s[size] ^ _t[size];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief cc_cmp_safe(num, pt1, pt2) compares two array ptr1 and ptr2 of num bytes.
|
||||
@discussion The execution time/cycles is independent of the data and therefore guarantees no leak about the data. However, the execution time depends on num.
|
||||
@param num number of bytes in each array
|
||||
@param ptr1 input array
|
||||
@param ptr2 input array
|
||||
@return returns 0 if the num bytes starting at ptr1 are identical to the num bytes starting at ptr2 and 1 if they are different or if num is 0 (empty arrays).
|
||||
*/
|
||||
CC_NONNULL2 CC_NONNULL3
|
||||
int cc_cmp_safe (size_t num, const void * ptr1, const void * ptr2);
|
||||
|
||||
/* Exchange S and T of any type. NOTE: Both and S and T are evaluated
|
||||
mutliple times and MUST NOT be expressions. */
|
||||
#define CC_SWAP(S,T) do { \
|
||||
__typeof__(S) _cc_swap_tmp = S; S = T; T = _cc_swap_tmp; \
|
||||
} while(0)
|
||||
|
||||
/* Return the maximum value between S and T. */
|
||||
#define CC_MAX(S, T) ({__typeof__(S) _cc_max_s = S; __typeof__(T) _cc_max_t = T; _cc_max_s > _cc_max_t ? _cc_max_s : _cc_max_t;})
|
||||
|
||||
/* Return the minimum value between S and T. */
|
||||
#define CC_MIN(S, T) ({__typeof__(S) _cc_min_s = S; __typeof__(T) _cc_min_t = T; _cc_min_s <= _cc_min_t ? _cc_min_s : _cc_min_t;})
|
||||
|
||||
#endif /* _CORECRYPTO_CC_H_ */
|
||||
|
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* cc_config.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 11/16/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CC_CONFIG_H_
|
||||
#define _CORECRYPTO_CC_CONFIG_H_
|
||||
|
||||
/* A word about configuration macros:
|
||||
|
||||
Conditional configuration macros specific to corecrypto should be named CORECRYPTO_xxx
|
||||
or CCxx_yyy and be defined to be either 0 or 1 in this file. You can add an
|
||||
#ifndef #error construct at the end of this file to make sure it's always defined.
|
||||
|
||||
They should always be tested using the #if directive, never the #ifdef directive.
|
||||
|
||||
No other conditional macros shall ever be used (except in this file)
|
||||
|
||||
Configuration Macros that are defined outside of corecrypto (eg: KERNEL, DEBUG, ...)
|
||||
shall only be used in this file to define CCxxx macros.
|
||||
|
||||
External macros should be assumed to be either undefined, defined with no value,
|
||||
or defined as true or false. We shall strive to build with -Wundef whenever possible,
|
||||
so the following construct should be used to test external macros in this file:
|
||||
|
||||
#if defined(DEBUG) && (DEBUG)
|
||||
#define CORECRYPTO_DEBUG 1
|
||||
#else
|
||||
#define CORECRYPTO_DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
It is acceptable to define a conditional CC_xxxx macro in an implementation file,
|
||||
to be used only in this file.
|
||||
|
||||
The current code is not guaranteed to follow those rules, but should be fixed to.
|
||||
|
||||
Corecrypto requires GNU and C99 compatibility.
|
||||
Typically enabled by passing --gnu --c99 to the compiler (eg. armcc)
|
||||
|
||||
*/
|
||||
|
||||
//Do not set these macros to 1, unless you are developing/testing for Windows
|
||||
#define CORECRYPTO_SIMULATE_WINDOWS_ENVIRONMENT 0
|
||||
#define CORECRYPTO_HACK_FOR_WINDOWS_DEVELOPMENT 0 //to be removed after <rdar://problem/26585938> port corecrypto to Windows
|
||||
|
||||
//this macro is used to turn on/off usage of transparent union in corecrypto
|
||||
//it should be commented out in corecrypto and be used only by the software that use corecrypto
|
||||
//#define CORECRYPTO_DONOT_USE_TRANSPARENT_UNION
|
||||
#ifdef CORECRYPTO_DONOT_USE_TRANSPARENT_UNION
|
||||
#define CORECRYPTO_USE_TRANSPARENT_UNION 0
|
||||
#else
|
||||
#define CORECRYPTO_USE_TRANSPARENT_UNION 1
|
||||
#endif
|
||||
|
||||
#if (defined(DEBUG) && (DEBUG)) || defined(_DEBUG) //MSVC defines _DEBUG
|
||||
/* CC_DEBUG is already used in CommonCrypto */
|
||||
#define CORECRYPTO_DEBUG 1
|
||||
#else
|
||||
#define CORECRYPTO_DEBUG 0
|
||||
#endif
|
||||
|
||||
// This macro can be used to enable prints when a condition in the macro "cc_require"
|
||||
// is false. This is especially useful to confirm that negative testing fails
|
||||
// at the intended location
|
||||
#define CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS 0
|
||||
|
||||
#if defined(KERNEL) && (KERNEL)
|
||||
#define CC_KERNEL 1 // KEXT, XNU repo or kernel components such as AppleKeyStore
|
||||
#else
|
||||
#define CC_KERNEL 0
|
||||
#endif
|
||||
|
||||
// LINUX_BUILD_TEST is for sanity check of the configuration
|
||||
// > xcodebuild -scheme "corecrypto_test" OTHER_CFLAGS="$(values) -DLINUX_BUILD_TEST"
|
||||
#if defined(__linux__) || defined(LINUX_BUILD_TEST)
|
||||
#define CC_LINUX 1
|
||||
#else
|
||||
#define CC_LINUX 0
|
||||
#endif
|
||||
|
||||
#if defined(USE_L4) && (USE_L4)
|
||||
#define CC_USE_L4 1
|
||||
#else
|
||||
#define CC_USE_L4 0
|
||||
#endif
|
||||
|
||||
#if defined(USE_SEPROM) && (USE_SEPROM)
|
||||
#define CC_USE_SEPROM 1
|
||||
#else
|
||||
#define CC_USE_SEPROM 0
|
||||
#endif
|
||||
|
||||
#if defined(USE_S3) && (USE_S3)
|
||||
#define CC_USE_S3 1
|
||||
#else
|
||||
#define CC_USE_S3 0
|
||||
#endif
|
||||
|
||||
#if (defined(ICE_FEATURES_ENABLED)) || (defined(MAVERICK) && (MAVERICK))
|
||||
#define CC_BASEBAND 1
|
||||
#else
|
||||
#define CC_BASEBAND 0
|
||||
#endif
|
||||
|
||||
#if defined(EFI) && (EFI)
|
||||
#define CC_EFI 1
|
||||
#else
|
||||
#define CC_EFI 0
|
||||
#endif
|
||||
|
||||
#if defined(IBOOT) && (IBOOT)
|
||||
#define CC_IBOOT 1
|
||||
#else
|
||||
#define CC_IBOOT 0
|
||||
#endif
|
||||
|
||||
// BB configuration
|
||||
#if CC_BASEBAND
|
||||
|
||||
// -- ENDIANESS
|
||||
#if defined(ENDIAN_LITTLE) || (defined(__arm__) && !defined(__BIG_ENDIAN))
|
||||
#define __LITTLE_ENDIAN__
|
||||
#elif !defined(ENDIAN_BIG) && !defined(__BIG_ENDIAN)
|
||||
#error Baseband endianess not defined.
|
||||
#endif
|
||||
#define AESOPT_ENDIAN_NO_FILE
|
||||
|
||||
// -- Architecture
|
||||
#define CCN_UNIT_SIZE 4 // 32 bits
|
||||
#define SAFE_IO // AES support for unaligned Input/Output
|
||||
|
||||
// -- External function
|
||||
#define assert ASSERT // sanity
|
||||
|
||||
// -- Warnings
|
||||
// Ignore irrelevant warnings after verification
|
||||
// #1254-D: arithmetic on pointer to void or function type
|
||||
// #186-D: pointless comparison of unsigned integer with zero
|
||||
// #546-D: transfer of control bypasses initialization of
|
||||
#if defined(__GNUC__)
|
||||
// warning: pointer of type 'void *' used in arithmetic
|
||||
#pragma GCC diagnostic ignored "-Wpointer-arith"
|
||||
#endif // arm or gnuc
|
||||
|
||||
#endif // CC_BASEBAND
|
||||
|
||||
//CC_XNU_KERNEL_AVAILABLE indicates the availibity of XNU kernel functions,
|
||||
//like what we have on OSX, iOS, tvOS, Watch OS
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#define CC_XNU_KERNEL_AVAILABLE 1
|
||||
#else
|
||||
#define CC_XNU_KERNEL_AVAILABLE 0
|
||||
#endif
|
||||
|
||||
#if !defined(CCN_UNIT_SIZE)
|
||||
#if defined(__arm64__) || defined(__x86_64__) || defined(_WIN64)
|
||||
#define CCN_UNIT_SIZE 8
|
||||
#elif defined(__arm__) || defined(__i386__) || defined(_WIN32)
|
||||
#define CCN_UNIT_SIZE 4
|
||||
#else
|
||||
#error undefined architecture
|
||||
#endif
|
||||
#endif /* !defined(CCN_UNIT_SIZE) */
|
||||
|
||||
|
||||
//this allows corecrypto Windows development using xcode
|
||||
#if defined(CORECRYPTO_SIMULATE_WINDOWS_ENVIRONMENT)
|
||||
#if CORECRYPTO_SIMULATE_WINDOWS_ENVIRONMENT && CC_XNU_KERNEL_AVAILABLE && CORECRYPTO_DEBUG
|
||||
#define CC_USE_ASM 0
|
||||
#define CC_USE_HEAP_FOR_WORKSPACE 1
|
||||
#if (CCN_UNIT_SIZE==8)
|
||||
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 0
|
||||
#else
|
||||
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(CCN_UINT128_SUPPORT_FOR_64BIT_ARCH)
|
||||
#if defined(_WIN64) && defined(_WIN32) && (CCN_UNIT_SIZE==8)
|
||||
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 0
|
||||
#elif defined(_WIN32)
|
||||
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 1//should not be a problem
|
||||
#else
|
||||
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __clang__ || CCN_UNIT_SIZE==8
|
||||
#define CC_ALIGNED(x) __attribute__ ((aligned(x)))
|
||||
#elif _MSC_VER
|
||||
#define CC_ALIGNED(x) __declspec(align(x))
|
||||
#else
|
||||
#define CC_ALIGNED(x) __attribute__ ((aligned((x)>8?8:(x))))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#define CCN_IOS 0
|
||||
#define CCN_OSX 1
|
||||
#endif
|
||||
|
||||
#if CC_USE_L4 || CC_USE_S3
|
||||
/* No dynamic linking allowed in L4, e.g. avoid nonlazy symbols */
|
||||
/* For corecrypto kext, CC_STATIC should be undefined */
|
||||
#define CC_STATIC 1
|
||||
#endif
|
||||
|
||||
#if !defined(CC_USE_HEAP_FOR_WORKSPACE)
|
||||
#if CC_USE_L4 || CC_IBOOT || defined(_MSC_VER)
|
||||
/* For L4, stack is too short, need to use HEAP for some computations */
|
||||
/* CC_USE_HEAP_FOR_WORKSPACE not supported for KERNEL! */
|
||||
#define CC_USE_HEAP_FOR_WORKSPACE 1
|
||||
#else
|
||||
#define CC_USE_HEAP_FOR_WORKSPACE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* memset_s is only available in few target */
|
||||
#if CC_KERNEL || CC_USE_SEPROM || defined(__CC_ARM) \
|
||||
|| defined(__hexagon__) || CC_EFI
|
||||
#define CC_HAS_MEMSET_S 0
|
||||
#else
|
||||
#define CC_HAS_MEMSET_S 1
|
||||
#endif
|
||||
|
||||
// Include target conditionals if available.
|
||||
#if defined(__has_include) /* portability */
|
||||
#if __has_include(<TargetConditionals.h>)
|
||||
#include <TargetConditionals.h>
|
||||
#endif /* __has_include(<TargetConditionals.h>) */
|
||||
#endif /* defined(__has_include) */
|
||||
|
||||
//- functions implemented in assembly ------------------------------------------
|
||||
//this the list of corecrypto clients that use assembly and the clang compiler
|
||||
#if !(CC_XNU_KERNEL_AVAILABLE || CC_KERNEL || CC_USE_L4 || CC_IBOOT || CC_USE_SEPROM || CC_USE_S3) && !defined(_WIN32) && CORECRYPTO_DEBUG
|
||||
#warning "You are using the default corecrypto configuration, assembly optimizations may not be available for your platform"
|
||||
#endif
|
||||
|
||||
// use this macro to strictly disable assembly regardless of cpu/os/compiler/etc
|
||||
#if !defined(CC_USE_ASM)
|
||||
#if defined(_MSC_VER) || CC_LINUX || CC_EFI || CC_BASEBAND
|
||||
#define CC_USE_ASM 0
|
||||
#else
|
||||
#define CC_USE_ASM 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-(1) ARM V7
|
||||
#if defined(_ARM_ARCH_7) && __clang__ && CC_USE_ASM
|
||||
#define CCN_DEDICATED_SQR 1
|
||||
#define CCN_MUL_KARATSUBA 0 // no performance improvement
|
||||
#define CCN_ADD_ASM 1
|
||||
#define CCN_SUB_ASM 1
|
||||
#define CCN_MUL_ASM 0
|
||||
#define CCN_ADDMUL1_ASM 1
|
||||
#define CCN_MUL1_ASM 1
|
||||
#define CCN_CMP_ASM 1
|
||||
#define CCN_ADD1_ASM 0
|
||||
#define CCN_SUB1_ASM 0
|
||||
#define CCN_N_ASM 1
|
||||
#define CCN_SET_ASM 1
|
||||
#define CCN_SHIFT_RIGHT_ASM 1
|
||||
#define CCAES_ARM_ASM 1
|
||||
#define CCAES_INTEL_ASM 0
|
||||
#if CC_KERNEL || CC_USE_L4 || CC_IBOOT || CC_USE_SEPROM || CC_USE_S3
|
||||
#define CCAES_MUX 0
|
||||
#else
|
||||
#define CCAES_MUX 1
|
||||
#endif
|
||||
#define CCN_USE_BUILTIN_CLZ 1
|
||||
#define CCSHA1_VNG_INTEL 0
|
||||
#define CCSHA2_VNG_INTEL 0
|
||||
|
||||
#if defined(__ARM_NEON__) || CC_KERNEL
|
||||
#define CCSHA1_VNG_ARMV7NEON 1
|
||||
#define CCSHA2_VNG_ARMV7NEON 1
|
||||
#else /* !defined(__ARM_NEON__) */
|
||||
#define CCSHA1_VNG_ARMV7NEON 0
|
||||
#define CCSHA2_VNG_ARMV7NEON 0
|
||||
#endif /* !defined(__ARM_NEON__) */
|
||||
#define CCSHA256_ARMV6M_ASM 0
|
||||
|
||||
//-(2) ARM 64
|
||||
#elif (defined(__x86_64__) || defined(__i386__)) && __clang__ && CC_USE_ASM
|
||||
#define CCN_DEDICATED_SQR 1
|
||||
#define CCN_MUL_KARATSUBA 1 // 4*n CCN_UNIT extra memory required.
|
||||
/* These assembly routines only work for a single CCN_UNIT_SIZE. */
|
||||
#if (defined(__x86_64__) && CCN_UNIT_SIZE == 8) || (defined(__i386__) && CCN_UNIT_SIZE == 4)
|
||||
#define CCN_ADD_ASM 1
|
||||
#define CCN_SUB_ASM 1
|
||||
#define CCN_MUL_ASM 1
|
||||
#else
|
||||
#define CCN_ADD_ASM 0
|
||||
#define CCN_SUB_ASM 0
|
||||
#define CCN_MUL_ASM 0
|
||||
#endif
|
||||
|
||||
#if (defined(__x86_64__) && CCN_UNIT_SIZE == 8)
|
||||
#define CCN_CMP_ASM 1
|
||||
#define CCN_N_ASM 1
|
||||
#define CCN_SHIFT_RIGHT_ASM 1
|
||||
#else
|
||||
#define CCN_CMP_ASM 0
|
||||
#define CCN_N_ASM 0
|
||||
#define CCN_SHIFT_RIGHT_ASM 0
|
||||
#endif
|
||||
|
||||
#define CCN_ADDMUL1_ASM 0
|
||||
#define CCN_MUL1_ASM 0
|
||||
#define CCN_ADD1_ASM 0
|
||||
#define CCN_SUB1_ASM 0
|
||||
#define CCN_SET_ASM 0
|
||||
#define CCAES_ARM_ASM 0
|
||||
#define CCAES_INTEL_ASM 1
|
||||
#define CCAES_MUX 0
|
||||
#define CCN_USE_BUILTIN_CLZ 0
|
||||
#define CCSHA1_VNG_INTEL 1
|
||||
#define CCSHA2_VNG_INTEL 1
|
||||
#define CCSHA1_VNG_ARMV7NEON 0
|
||||
#define CCSHA2_VNG_ARMV7NEON 0
|
||||
#define CCSHA256_ARMV6M_ASM 0
|
||||
|
||||
//-(4) disable assembly
|
||||
#else
|
||||
#if CCN_UINT128_SUPPORT_FOR_64BIT_ARCH
|
||||
#define CCN_DEDICATED_SQR 1
|
||||
#else
|
||||
#define CCN_DEDICATED_SQR 0 //when assembly is off and 128-bit integers are not supported, dedicated square is off. This is the case on Windows
|
||||
#endif
|
||||
#define CCN_MUL_KARATSUBA 1 // 4*n CCN_UNIT extra memory required.
|
||||
#define CCN_ADD_ASM 0
|
||||
#define CCN_SUB_ASM 0
|
||||
#define CCN_MUL_ASM 0
|
||||
#define CCN_ADDMUL1_ASM 0
|
||||
#define CCN_MUL1_ASM 0
|
||||
#define CCN_CMP_ASM 0
|
||||
#define CCN_ADD1_ASM 0
|
||||
#define CCN_SUB1_ASM 0
|
||||
#define CCN_N_ASM 0
|
||||
#define CCN_SET_ASM 0
|
||||
#define CCN_SHIFT_RIGHT_ASM 0
|
||||
#define CCAES_ARM_ASM 0
|
||||
#define CCAES_INTEL_ASM 0
|
||||
#define CCAES_MUX 0
|
||||
#define CCN_USE_BUILTIN_CLZ 0
|
||||
#define CCSHA1_VNG_INTEL 0
|
||||
#define CCSHA2_VNG_INTEL 0
|
||||
#define CCSHA1_VNG_ARMV7NEON 0
|
||||
#define CCSHA2_VNG_ARMV7NEON 0
|
||||
#define CCSHA256_ARMV6M_ASM 0
|
||||
|
||||
#endif
|
||||
|
||||
#define CC_INLINE static inline
|
||||
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
// Non null for transparent unions is ambiguous and cause problems
|
||||
// for most tools (GCC and others: 23919290).
|
||||
#define CC_NONNULL_TU(N)
|
||||
#else
|
||||
#define CC_NONNULL_TU(N) CC_NONNULL(N)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CC_NORETURN __attribute__((__noreturn__))
|
||||
#define CC_NOTHROW __attribute__((__nothrow__))
|
||||
#define CC_NONNULL(N) __attribute__((__nonnull__ N))
|
||||
#define CC_NONNULL1 __attribute__((__nonnull__(1)))
|
||||
#define CC_NONNULL2 __attribute__((__nonnull__(2)))
|
||||
#define CC_NONNULL3 __attribute__((__nonnull__(3)))
|
||||
#define CC_NONNULL4 __attribute__((__nonnull__(4)))
|
||||
#define CC_NONNULL5 __attribute__((__nonnull__(5)))
|
||||
#define CC_NONNULL6 __attribute__((__nonnull__(6)))
|
||||
#define CC_NONNULL7 __attribute__((__nonnull__(7)))
|
||||
#define CC_NONNULL_ALL __attribute__((__nonnull__))
|
||||
#define CC_SENTINEL __attribute__((__sentinel__))
|
||||
#define CC_CONST __attribute__((__const__))
|
||||
#define CC_PURE __attribute__((__pure__))
|
||||
#define CC_WARN_RESULT __attribute__((__warn_unused_result__))
|
||||
#define CC_MALLOC __attribute__((__malloc__))
|
||||
#define CC_UNUSED __attribute__((unused))
|
||||
#else /* !__GNUC__ */
|
||||
/*! @parseOnly */
|
||||
#define CC_UNUSED
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL(N)
|
||||
/*! @parseOnly */
|
||||
#define CC_NORETURN
|
||||
/*! @parseOnly */
|
||||
#define CC_NOTHROW
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL1
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL2
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL3
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL4
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL5
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL6
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL7
|
||||
/*! @parseOnly */
|
||||
#define CC_NONNULL_ALL
|
||||
/*! @parseOnly */
|
||||
#define CC_SENTINEL
|
||||
/*! @parseOnly */
|
||||
#define CC_CONST
|
||||
/*! @parseOnly */
|
||||
#define CC_PURE
|
||||
/*! @parseOnly */
|
||||
#define CC_WARN_RESULT
|
||||
/*! @parseOnly */
|
||||
#define CC_MALLOC
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
|
||||
#endif /* _CORECRYPTO_CC_CONFIG_H_ */
|
70
include/corecrypto/cc_debug.h
Normal file
70
include/corecrypto/cc_debug.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* cc_debug.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 01/25/2012
|
||||
*
|
||||
* Copyright (c) 2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
//debug configuration header file
|
||||
#ifndef _CORECRYPTO_CCN_DEBUG_H_
|
||||
#define _CORECRYPTO_CCN_DEBUG_H_
|
||||
|
||||
#include <corecrypto/cc_config.h>
|
||||
|
||||
// DO NOT INCLUDE this HEADER file in CoreCrypto files added for XNU project or headers
|
||||
// included by external clients.
|
||||
|
||||
// ========================
|
||||
// Printf for corecrypto
|
||||
// ========================
|
||||
#if CC_KERNEL
|
||||
#include <pexpert/pexpert.h>
|
||||
#define cc_printf(x...) kprintf(x)
|
||||
extern int printf(const char *format, ...) __printflike(1,2);
|
||||
#elif CC_USE_S3
|
||||
#include <stdio.h>
|
||||
#define cc_printf(x...) printf(x)
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define cc_printf(x...) fprintf(stderr, x)
|
||||
#endif
|
||||
|
||||
// ========================
|
||||
// Integer types
|
||||
// ========================
|
||||
|
||||
#if CC_KERNEL
|
||||
/* Those are not defined in libkern */
|
||||
#define PRIx64 "llx"
|
||||
#define PRIx32 "x"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIx8 "hhx"
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if CCN_UNIT_SIZE == 8
|
||||
#define CCPRIx_UNIT ".016" PRIx64
|
||||
#elif CCN_UNIT_SIZE == 4
|
||||
#define CCPRIx_UNIT ".08" PRIx32
|
||||
#elif CCN_UNIT_SIZE == 2
|
||||
#define CCPRIx_UNIT ".04" PRIx16
|
||||
#elif CCN_UNIT_SIZE == 1
|
||||
#define CCPRIx_UNIT ".02" PRIx8
|
||||
#else
|
||||
#error invalid CCN_UNIT_SIZE
|
||||
#endif
|
||||
|
||||
// ========================
|
||||
// Print utilities for corecrypto
|
||||
// ========================
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
|
||||
/* Print a byte array of arbitrary size */
|
||||
void cc_print(const char *label, size_t count, const uint8_t *s);
|
||||
|
||||
#endif /* _CORECRYPTO_CCN_DEBUG_H_ */
|
120
include/corecrypto/cc_macros.h
Normal file
120
include/corecrypto/cc_macros.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* cc_macros.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 01/11/2012
|
||||
*
|
||||
* Copyright (c) 2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CC_MACROS_H_
|
||||
#define _CORECRYPTO_CC_MACROS_H_
|
||||
|
||||
#include <corecrypto/cc_config.h>
|
||||
|
||||
#ifndef __CC_DEBUG_ASSERT_COMPONENT_NAME_STRING
|
||||
#define __CC_DEBUG_ASSERT_COMPONENT_NAME_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef __CC_DEBUG_ASSERT_PRODUCTION_CODE
|
||||
#define __CC_DEBUG_ASSERT_PRODUCTION_CODE !CORECRYPTO_DEBUG
|
||||
#endif
|
||||
|
||||
#if CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS
|
||||
|
||||
#if !CC_KERNEL
|
||||
#include <string.h> // for strstr
|
||||
#endif // !CC_KERNEL
|
||||
|
||||
CC_UNUSED static char *cc_strstr(const char *file) {
|
||||
#if CC_KERNEL
|
||||
(void) file;
|
||||
#else
|
||||
const char cc_char []="corecrypto";
|
||||
char *p=strstr(file, cc_char);
|
||||
if (p) return (p+strlen(cc_char)+1);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define __CC_DEBUG_REQUIRE_MESSAGE(name, assertion, label, message, file, line, value) \
|
||||
{char *___t = cc_strstr(file); cc_printf( "require: %s, %s%s:%d\n", assertion, (message!=0) ? message : "", ___t==NULL?file:___t, line);}
|
||||
|
||||
#endif // CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS
|
||||
|
||||
#ifndef cc_require
|
||||
#if (__CC_DEBUG_ASSERT_PRODUCTION_CODE) || (!CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS)
|
||||
#if defined(_WIN32) && defined (__clang__)
|
||||
#define cc_require(assertion, exceptionLabel) \
|
||||
do { \
|
||||
if (!(assertion) ) { \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
#else
|
||||
#define cc_require(assertion, exceptionLabel) \
|
||||
do { \
|
||||
if ( __builtin_expect(!(assertion), 0) ) { \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
#endif
|
||||
#else
|
||||
#define cc_require(assertion, exceptionLabel) \
|
||||
do { \
|
||||
if ( __builtin_expect(!(assertion), 0) ) { \
|
||||
__CC_DEBUG_REQUIRE_MESSAGE(__CC_DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
||||
#assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef cc_require_action
|
||||
#if __CC_DEBUG_ASSERT_PRODUCTION_CODE || (!CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS)
|
||||
#if defined(_WIN32) && defined(__clang__)
|
||||
#define cc_require_action(assertion, exceptionLabel, action) \
|
||||
do \
|
||||
{ \
|
||||
if (!(assertion)) \
|
||||
{ \
|
||||
{ \
|
||||
action; \
|
||||
} \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
#else
|
||||
#define cc_require_action(assertion, exceptionLabel, action) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
{ \
|
||||
action; \
|
||||
} \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
#endif
|
||||
#else
|
||||
#define cc_require_action(assertion, exceptionLabel, action) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
__CC_DEBUG_REQUIRE_MESSAGE( \
|
||||
__CC_DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
||||
#assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \
|
||||
{ \
|
||||
action; \
|
||||
} \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _CORECRYPTO_CC_MACROS_H_ */
|
455
include/corecrypto/cc_priv.h
Normal file
455
include/corecrypto/cc_priv.h
Normal file
@ -0,0 +1,455 @@
|
||||
/*
|
||||
* cc_priv.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/01/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CC_PRIV_H_
|
||||
#define _CORECRYPTO_CC_PRIV_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* defines the following macros :
|
||||
|
||||
CC_MEMCPY : optimized memcpy.
|
||||
CC_MEMMOVE : optimized memmove.
|
||||
CC_MEMSET : optimized memset.
|
||||
|
||||
CC_STORE32_BE : store 32 bit value in big endian in unaligned buffer.
|
||||
CC_STORE32_LE : store 32 bit value in little endian in unaligned buffer.
|
||||
CC_STORE64_BE : store 64 bit value in big endian in unaligned buffer.
|
||||
CC_STORE64_LE : store 64 bit value in little endian in unaligned buffer.
|
||||
|
||||
CC_LOAD32_BE : load 32 bit value in big endian from unaligned buffer.
|
||||
CC_LOAD32_LE : load 32 bit value in little endian from unaligned buffer.
|
||||
CC_LOAD64_BE : load 64 bit value in big endian from unaligned buffer.
|
||||
CC_LOAD64_LE : load 64 bit value in little endian from unaligned buffer.
|
||||
|
||||
CC_ROR : Rotate Right 32 bits. Rotate count can be a variable.
|
||||
CC_ROL : Rotate Left 32 bits. Rotate count can be a variable.
|
||||
CC_RORc : Rotate Right 32 bits. Rotate count must be a constant.
|
||||
CC_ROLc : Rotate Left 32 bits. Rotate count must be a constant.
|
||||
|
||||
CC_ROR64 : Rotate Right 64 bits. Rotate count can be a variable.
|
||||
CC_ROL64 : Rotate Left 64 bits. Rotate count can be a variable.
|
||||
CC_ROR64c : Rotate Right 64 bits. Rotate count must be a constant.
|
||||
CC_ROL64c : Rotate Left 64 bits. Rotate count must be a constant.
|
||||
|
||||
CC_BSWAP : byte swap a 32 bits variable.
|
||||
|
||||
CC_H2BE32 : convert a 32 bits value between host and big endian order.
|
||||
CC_H2LE32 : convert a 32 bits value between host and little endian order.
|
||||
|
||||
The following are not defined yet... define them if needed.
|
||||
|
||||
CC_BSWAPc : byte swap a 32 bits constant
|
||||
|
||||
CC_BSWAP64 : byte swap a 64 bits variable
|
||||
CC_BSWAP64c : byte swap a 64 bits constant
|
||||
|
||||
CC_READ_LE32 : read a 32 bits little endian value
|
||||
CC_READ_LE64 : read a 64 bits little endian value
|
||||
CC_READ_BE32 : read a 32 bits big endian value
|
||||
CC_READ_BE64 : read a 64 bits big endian value
|
||||
|
||||
CC_WRITE_LE32 : write a 32 bits little endian value
|
||||
CC_WRITE_LE64 : write a 64 bits little endian value
|
||||
CC_WRITE_BE32 : write a 32 bits big endian value
|
||||
CC_WRITE_BE64 : write a 64 bits big endian value
|
||||
|
||||
CC_H2BE64 : convert a 64 bits value between host and big endian order
|
||||
CC_H2LE64 : convert a 64 bits value between host and little endian order
|
||||
|
||||
*/
|
||||
|
||||
/* TODO: optimized versions */
|
||||
#define CC_MEMCPY(D,S,L) memcpy((D),(S),(L))
|
||||
#define CC_MEMMOVE(D,S,L) memmove((D),(S),(L))
|
||||
#define CC_MEMSET(D,V,L) memset((D),(V),(L))
|
||||
|
||||
// MARK: - Loads and Store
|
||||
|
||||
// MARK: -- 32 bits - little endian
|
||||
|
||||
// MARK: --- Default version
|
||||
|
||||
#define CC_STORE32_LE(x, y) do { \
|
||||
((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255); \
|
||||
((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255); \
|
||||
((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255); \
|
||||
((unsigned char *)(y))[0] = (unsigned char)((x)&255); \
|
||||
} while(0)
|
||||
|
||||
#define CC_LOAD32_LE(x, y) do { \
|
||||
x = ((uint32_t)(((const unsigned char *)(y))[3] & 255)<<24) | \
|
||||
((uint32_t)(((const unsigned char *)(y))[2] & 255)<<16) | \
|
||||
((uint32_t)(((const unsigned char *)(y))[1] & 255)<<8) | \
|
||||
((uint32_t)(((const unsigned char *)(y))[0] & 255)); \
|
||||
} while(0)
|
||||
|
||||
// MARK: -- 64 bits - little endian
|
||||
|
||||
#define CC_STORE64_LE(x, y) do { \
|
||||
((unsigned char *)(y))[7] = (unsigned char)(((x)>>56)&255); \
|
||||
((unsigned char *)(y))[6] = (unsigned char)(((x)>>48)&255); \
|
||||
((unsigned char *)(y))[5] = (unsigned char)(((x)>>40)&255); \
|
||||
((unsigned char *)(y))[4] = (unsigned char)(((x)>>32)&255); \
|
||||
((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255); \
|
||||
((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255); \
|
||||
((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255); \
|
||||
((unsigned char *)(y))[0] = (unsigned char)((x)&255); \
|
||||
} while(0)
|
||||
|
||||
#define CC_LOAD64_LE(x, y) do { \
|
||||
x = (((uint64_t)(((const unsigned char *)(y))[7] & 255))<<56) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[6] & 255))<<48) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[5] & 255))<<40) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[4] & 255))<<32) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[3] & 255))<<24) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[2] & 255))<<16) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[1] & 255))<<8) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[0] & 255))); \
|
||||
} while(0)
|
||||
|
||||
// MARK: -- 32 bits - big endian
|
||||
// MARK: --- intel version
|
||||
|
||||
#if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
|
||||
|
||||
#define CC_STORE32_BE(x, y) \
|
||||
__asm__ __volatile__ ( \
|
||||
"bswapl %0 \n\t" \
|
||||
"movl %0,(%1)\n\t" \
|
||||
"bswapl %0 \n\t" \
|
||||
::"r"(x), "r"(y))
|
||||
|
||||
#define CC_LOAD32_BE(x, y) \
|
||||
__asm__ __volatile__ ( \
|
||||
"movl (%1),%0\n\t" \
|
||||
"bswapl %0\n\t" \
|
||||
:"=r"(x): "r"(y))
|
||||
|
||||
#else
|
||||
// MARK: --- default version
|
||||
#define CC_STORE32_BE(x, y) do { \
|
||||
((unsigned char *)(y))[0] = (unsigned char)(((x)>>24)&255); \
|
||||
((unsigned char *)(y))[1] = (unsigned char)(((x)>>16)&255); \
|
||||
((unsigned char *)(y))[2] = (unsigned char)(((x)>>8)&255); \
|
||||
((unsigned char *)(y))[3] = (unsigned char)((x)&255); \
|
||||
} while(0)
|
||||
|
||||
#define CC_LOAD32_BE(x, y) do { \
|
||||
x = ((uint32_t)(((const unsigned char *)(y))[0] & 255)<<24) | \
|
||||
((uint32_t)(((const unsigned char *)(y))[1] & 255)<<16) | \
|
||||
((uint32_t)(((const unsigned char *)(y))[2] & 255)<<8) | \
|
||||
((uint32_t)(((const unsigned char *)(y))[3] & 255)); \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: -- 64 bits - big endian
|
||||
|
||||
// MARK: --- intel 64 bits version
|
||||
|
||||
#if defined(__x86_64__) && !defined (_MSC_VER)
|
||||
|
||||
#define CC_STORE64_BE(x, y) \
|
||||
__asm__ __volatile__ ( \
|
||||
"bswapq %0 \n\t" \
|
||||
"movq %0,(%1)\n\t" \
|
||||
"bswapq %0 \n\t" \
|
||||
::"r"(x), "r"(y))
|
||||
|
||||
#define CC_LOAD64_BE(x, y) \
|
||||
__asm__ __volatile__ ( \
|
||||
"movq (%1),%0\n\t" \
|
||||
"bswapq %0\n\t" \
|
||||
:"=r"(x): "r"(y))
|
||||
|
||||
#else
|
||||
|
||||
// MARK: --- default version
|
||||
|
||||
#define CC_STORE64_BE(x, y) do { \
|
||||
((unsigned char *)(y))[0] = (unsigned char)(((x)>>56)&255); \
|
||||
((unsigned char *)(y))[1] = (unsigned char)(((x)>>48)&255); \
|
||||
((unsigned char *)(y))[2] = (unsigned char)(((x)>>40)&255); \
|
||||
((unsigned char *)(y))[3] = (unsigned char)(((x)>>32)&255); \
|
||||
((unsigned char *)(y))[4] = (unsigned char)(((x)>>24)&255); \
|
||||
((unsigned char *)(y))[5] = (unsigned char)(((x)>>16)&255); \
|
||||
((unsigned char *)(y))[6] = (unsigned char)(((x)>>8)&255); \
|
||||
((unsigned char *)(y))[7] = (unsigned char)((x)&255); \
|
||||
} while(0)
|
||||
|
||||
#define CC_LOAD64_BE(x, y) do { \
|
||||
x = (((uint64_t)(((const unsigned char *)(y))[0] & 255))<<56) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[1] & 255))<<48) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[2] & 255))<<40) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[3] & 255))<<32) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[4] & 255))<<24) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[5] & 255))<<16) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[6] & 255))<<8) | \
|
||||
(((uint64_t)(((const unsigned char *)(y))[7] & 255))); \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: - 32-bit Rotates
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// MARK: -- MSVC version
|
||||
|
||||
#include <stdlib.h>
|
||||
#if !defined(__clang__)
|
||||
#pragma intrinsic(_lrotr,_lrotl)
|
||||
#endif
|
||||
#define CC_ROR(x,n) _lrotr(x,n)
|
||||
#define CC_ROL(x,n) _lrotl(x,n)
|
||||
#define CC_RORc(x,n) _lrotr(x,n)
|
||||
#define CC_ROLc(x,n) _lrotl(x,n)
|
||||
|
||||
#elif (defined(__i386__) || defined(__x86_64__))
|
||||
// MARK: -- intel asm version
|
||||
|
||||
CC_INLINE uint32_t CC_ROL(uint32_t word, int i)
|
||||
{
|
||||
__asm__ ("roll %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
CC_INLINE uint32_t CC_ROR(uint32_t word, int i)
|
||||
{
|
||||
__asm__ ("rorl %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
/* Need to be a macro here, because 'i' is an immediate (constant) */
|
||||
#define CC_ROLc(word, i) \
|
||||
({ uint32_t _word=(word); \
|
||||
__asm__ __volatile__ ("roll %2,%0" \
|
||||
:"=r" (_word) \
|
||||
:"0" (_word),"I" (i)); \
|
||||
_word; \
|
||||
})
|
||||
|
||||
|
||||
#define CC_RORc(word, i) \
|
||||
({ uint32_t _word=(word); \
|
||||
__asm__ __volatile__ ("rorl %2,%0" \
|
||||
:"=r" (_word) \
|
||||
:"0" (_word),"I" (i)); \
|
||||
_word; \
|
||||
})
|
||||
|
||||
#else
|
||||
|
||||
// MARK: -- default version
|
||||
|
||||
CC_INLINE uint32_t CC_ROL(uint32_t word, int i)
|
||||
{
|
||||
return ( (word<<(i&31)) | (word>>(32-(i&31))) );
|
||||
}
|
||||
|
||||
CC_INLINE uint32_t CC_ROR(uint32_t word, int i)
|
||||
{
|
||||
return ( (word>>(i&31)) | (word<<(32-(i&31))) );
|
||||
}
|
||||
|
||||
#define CC_ROLc(x, y) CC_ROL(x, y)
|
||||
#define CC_RORc(x, y) CC_ROR(x, y)
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: - 64 bits rotates
|
||||
|
||||
#if defined(__x86_64__) && !defined(_MSC_VER) //clang _MSVC doesn't support GNU-style inline assembly
|
||||
// MARK: -- intel 64 asm version
|
||||
|
||||
CC_INLINE uint64_t CC_ROL64(uint64_t word, int i)
|
||||
{
|
||||
__asm__("rolq %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
CC_INLINE uint64_t CC_ROR64(uint64_t word, int i)
|
||||
{
|
||||
__asm__("rorq %%cl,%0"
|
||||
:"=r" (word)
|
||||
:"0" (word),"c" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
/* Need to be a macro here, because 'i' is an immediate (constant) */
|
||||
#define CC_ROL64c(word, i) \
|
||||
({ \
|
||||
uint64_t _word=(word); \
|
||||
__asm__("rolq %2,%0" \
|
||||
:"=r" (_word) \
|
||||
:"0" (_word),"J" (i)); \
|
||||
_word; \
|
||||
})
|
||||
|
||||
#define CC_ROR64c(word, i) \
|
||||
({ \
|
||||
uint64_t _word=(word); \
|
||||
__asm__("rorq %2,%0" \
|
||||
:"=r" (_word) \
|
||||
:"0" (_word),"J" (i)); \
|
||||
_word; \
|
||||
})
|
||||
|
||||
|
||||
#else /* Not x86_64 */
|
||||
|
||||
// MARK: -- default C version
|
||||
|
||||
CC_INLINE uint64_t CC_ROL64(uint64_t word, int i)
|
||||
{
|
||||
return ( (word<<(i&63)) | (word>>(64-(i&63))) );
|
||||
}
|
||||
|
||||
CC_INLINE uint64_t CC_ROR64(uint64_t word, int i)
|
||||
{
|
||||
return ( (word>>(i&63)) | (word<<(64-(i&63))) );
|
||||
}
|
||||
|
||||
#define CC_ROL64c(x, y) CC_ROL64(x, y)
|
||||
#define CC_ROR64c(x, y) CC_ROR64(x, y)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// MARK: - Byte Swaps
|
||||
|
||||
CC_INLINE uint32_t CC_BSWAP(uint32_t x)
|
||||
{
|
||||
return (
|
||||
((x>>24)&0x000000FF) |
|
||||
((x<<24)&0xFF000000) |
|
||||
((x>>8) &0x0000FF00) |
|
||||
((x<<8) &0x00FF0000)
|
||||
);
|
||||
}
|
||||
|
||||
#define CC_BSWAP64(x) \
|
||||
((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
|
||||
(((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
|
||||
(((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
|
||||
(((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
|
||||
(((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
|
||||
(((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
|
||||
(((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
|
||||
(((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#define CC_H2BE32(x) CC_BSWAP(x)
|
||||
#define CC_H2LE32(x) (x)
|
||||
#else
|
||||
#define CC_H2BE32(x) (x)
|
||||
#define CC_H2LE32(x) CC_BSWAP(x)
|
||||
#endif
|
||||
|
||||
|
||||
/* extract a byte portably */
|
||||
#ifdef _MSC_VER
|
||||
#define cc_byte(x, n) ((unsigned char)((x) >> (8 * (n))))
|
||||
#else
|
||||
#define cc_byte(x, n) (((x) >> (8 * (n))) & 255)
|
||||
#endif
|
||||
|
||||
/* HEAVISIDE_STEP (shifted by one)
|
||||
function f(x): x->0, when x=0
|
||||
x->1, when x>0
|
||||
Can also be seen as a bitwise operation:
|
||||
f(x): x -> y
|
||||
y[0]=(OR x[i]) for all i (all bits)
|
||||
y[i]=0 for all i>0
|
||||
Run in constant time (log2(<bitsize of x>))
|
||||
Useful to run constant time checks
|
||||
*/
|
||||
#define HEAVISIDE_STEP_UINT64(r,s) {uint64_t _t=s; \
|
||||
_t=(((_t)>>32) | (_t)); \
|
||||
_t=(0xFFFFFFFF + (_t & 0xFFFFFFFF)); \
|
||||
r=_t >> 32;}
|
||||
|
||||
#define HEAVISIDE_STEP_UINT32(r,s) {uint32_t _t=s; \
|
||||
_t=(((_t)>>16) | (_t)); \
|
||||
_t=(0xFFFF + (_t & 0xFFFF)); \
|
||||
r=_t >> 16;}
|
||||
|
||||
#define HEAVISIDE_STEP_UINT16(r,s) {uint32_t _t=s; \
|
||||
_t=(0xFFFF + ((_t) & 0xFFFF)); \
|
||||
r=_t >> 16;}
|
||||
|
||||
#define HEAVISIDE_STEP_UINT8(r,s) {uint16_t _t=s; \
|
||||
_t=(0xFF + ((_t) & 0xFF)); \
|
||||
r=_t >> 8;}
|
||||
|
||||
#define CC_HEAVISIDE_STEP(r,s) { \
|
||||
if (sizeof(s) == 1) {HEAVISIDE_STEP_UINT8(r,s);} \
|
||||
else if (sizeof(s) == 2) {HEAVISIDE_STEP_UINT16(r,s);} \
|
||||
else if (sizeof(s) == 4) {HEAVISIDE_STEP_UINT32(r,s);} \
|
||||
else if (sizeof(s) == 8) {HEAVISIDE_STEP_UINT64(r,s);} \
|
||||
else {r=(((s)==0)?0:1);} \
|
||||
}
|
||||
|
||||
/* Return 1 if x mod 4 =1,2,3, 0 otherwise */
|
||||
#define CC_CARRY_2BITS(x) (((x>>1) | x) & 0x1)
|
||||
#define CC_CARRY_3BITS(x) (((x>>2) | (x>>1) | x) & 0x1)
|
||||
|
||||
/* Set a variable to the biggest power of 2 which can be represented */
|
||||
#define MAX_POWER_OF_2(x) ((__typeof__(x))1<<(8*sizeof(x)-1))
|
||||
#define cc_ceiling(a,b) (((a)+((b)-1))/(b))
|
||||
#define CC_BITLEN_TO_BYTELEN(x) cc_ceiling((x), 8)
|
||||
|
||||
//cc_abort() is implemented to comply with FIPS 140-2. See radar 19129408
|
||||
void cc_abort(const char * msg , ...);
|
||||
|
||||
/*!
|
||||
@brief cc_muxp(s, a, b) is equivalent to z = s ? a : b, but it executes in constant time
|
||||
@param a input pointer
|
||||
@param b input pointer
|
||||
@param s The selection parameter s must be 0 or 1. if s is integer 1 a is returned. If s is integer 0, b is returned. Otherwise, the output is undefined.
|
||||
@return Returns a, if s is 1 and b if s is 0
|
||||
*/
|
||||
void *cc_muxp(int s, const void *a, const void *b);
|
||||
|
||||
/*!
|
||||
@brief cc_mux2p
|
||||
@param a input pointer
|
||||
@param b input pointer
|
||||
@param r_true output pointer: if s is integer 1 r_true=a is returned, otherwise r_true=b
|
||||
@param r_false output pointer: if s is integer 1 r_false=b is returned, otherwise r_false=a
|
||||
@param s The selection parameter s must be 0 or 1.
|
||||
@discussion Executes in constant time
|
||||
*/
|
||||
void cc_mux2p(int s, void **r_true, void **r_false, const void *a, const void *b);
|
||||
|
||||
/*!
|
||||
@brief CC_MUXU(s, a, b) is equivalent to z = s ? a : b, but it executes in constant time
|
||||
@param a input unsigned type
|
||||
@param b input unsigned type
|
||||
@param s The selection parameter s must be 0 or 1. if s is integer 1 a is returned. If s is integer 0, b is returned. Otherwise, the output is undefined.
|
||||
@param r output
|
||||
@return r = a, if s is 1 and b if s is 0
|
||||
*/
|
||||
#define CC_MUXU(r, s, a, b) \
|
||||
{ \
|
||||
__typeof__(r) _cond = ((__typeof__(r))(s)-(__typeof__(r))1); \
|
||||
r = (~_cond&(a))|(_cond&(b)); \
|
||||
}
|
||||
|
||||
int cc_is_compiled_with_tu(void);
|
||||
|
||||
#endif /* _CORECRYPTO_CC_PRIV_H_ */
|
106
include/corecrypto/ccaes.h
Normal file
106
include/corecrypto/ccaes.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* ccaes.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/10/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2013,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCAES_H_
|
||||
#define _CORECRYPTO_CCAES_H_
|
||||
|
||||
#include <corecrypto/cc_config.h>
|
||||
#include <corecrypto/ccmode.h>
|
||||
|
||||
#define CCAES_BLOCK_SIZE 16
|
||||
#define CCAES_KEY_SIZE_128 16
|
||||
#define CCAES_KEY_SIZE_192 24
|
||||
#define CCAES_KEY_SIZE_256 32
|
||||
|
||||
extern const struct ccmode_ecb ccaes_ltc_ecb_decrypt_mode;
|
||||
extern const struct ccmode_ecb ccaes_ltc_ecb_encrypt_mode;
|
||||
|
||||
extern const struct ccmode_cbc ccaes_gladman_cbc_encrypt_mode;
|
||||
extern const struct ccmode_cbc ccaes_gladman_cbc_decrypt_mode;
|
||||
|
||||
#if CCAES_ARM_ASM
|
||||
extern const struct ccmode_ecb ccaes_arm_ecb_encrypt_mode;
|
||||
extern const struct ccmode_ecb ccaes_arm_ecb_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_cbc ccaes_arm_cbc_encrypt_mode;
|
||||
extern const struct ccmode_cbc ccaes_arm_cbc_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_xts ccaes_arm_xts_encrypt_mode;
|
||||
extern const struct ccmode_xts ccaes_arm_xts_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_cfb ccaes_arm_cfb_encrypt_mode;
|
||||
extern const struct ccmode_cfb ccaes_arm_cfb_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_ofb ccaes_arm_ofb_crypt_mode;
|
||||
|
||||
#endif
|
||||
|
||||
#if CCAES_MUX
|
||||
extern const struct ccmode_cbc ccaes_ios_hardware_cbc_encrypt_mode;
|
||||
extern const struct ccmode_cbc ccaes_ios_hardware_cbc_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_cbc *ccaes_ios_mux_cbc_encrypt_mode(void);
|
||||
extern const struct ccmode_cbc *ccaes_ios_mux_cbc_decrypt_mode(void);
|
||||
#endif
|
||||
|
||||
#if CCAES_INTEL_ASM
|
||||
//extern const struct ccmode_ecb ccaes_intel_ecb_encrypt_mode;
|
||||
//extern const struct ccmode_ecb ccaes_intel_ecb_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_ecb ccaes_intel_ecb_encrypt_opt_mode;
|
||||
extern const struct ccmode_ecb ccaes_intel_ecb_encrypt_aesni_mode;
|
||||
|
||||
extern const struct ccmode_ecb ccaes_intel_ecb_decrypt_opt_mode;
|
||||
extern const struct ccmode_ecb ccaes_intel_ecb_decrypt_aesni_mode;
|
||||
|
||||
//extern const struct ccmode_cbc ccaes_intel_cbc_encrypt_mode;
|
||||
//extern const struct ccmode_cbc ccaes_intel_cbc_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_cbc ccaes_intel_cbc_encrypt_opt_mode;
|
||||
extern const struct ccmode_cbc ccaes_intel_cbc_encrypt_aesni_mode;
|
||||
|
||||
extern const struct ccmode_cbc ccaes_intel_cbc_decrypt_opt_mode;
|
||||
extern const struct ccmode_cbc ccaes_intel_cbc_decrypt_aesni_mode;
|
||||
|
||||
//extern const struct ccmode_xts ccaes_intel_xts_encrypt_mode;
|
||||
//extern const struct ccmode_xts ccaes_intel_xts_decrypt_mode;
|
||||
|
||||
extern const struct ccmode_xts ccaes_intel_xts_encrypt_opt_mode;
|
||||
extern const struct ccmode_xts ccaes_intel_xts_encrypt_aesni_mode;
|
||||
|
||||
extern const struct ccmode_xts ccaes_intel_xts_decrypt_opt_mode;
|
||||
extern const struct ccmode_xts ccaes_intel_xts_decrypt_aesni_mode;
|
||||
#endif
|
||||
|
||||
|
||||
/* Implementation Selectors: */
|
||||
const struct ccmode_ecb *ccaes_ecb_encrypt_mode(void);
|
||||
const struct ccmode_cbc *ccaes_cbc_encrypt_mode(void);
|
||||
const struct ccmode_cfb *ccaes_cfb_encrypt_mode(void);
|
||||
const struct ccmode_cfb8 *ccaes_cfb8_encrypt_mode(void);
|
||||
const struct ccmode_xts *ccaes_xts_encrypt_mode(void);
|
||||
const struct ccmode_gcm *ccaes_gcm_encrypt_mode(void);
|
||||
const struct ccmode_ccm *ccaes_ccm_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_ecb *ccaes_ecb_decrypt_mode(void);
|
||||
const struct ccmode_cbc *ccaes_cbc_decrypt_mode(void);
|
||||
const struct ccmode_cfb *ccaes_cfb_decrypt_mode(void);
|
||||
const struct ccmode_cfb8 *ccaes_cfb8_decrypt_mode(void);
|
||||
const struct ccmode_xts *ccaes_xts_decrypt_mode(void);
|
||||
const struct ccmode_gcm *ccaes_gcm_decrypt_mode(void);
|
||||
const struct ccmode_ccm *ccaes_ccm_decrypt_mode(void);
|
||||
|
||||
const struct ccmode_ctr *ccaes_ctr_crypt_mode(void);
|
||||
const struct ccmode_ofb *ccaes_ofb_crypt_mode(void);
|
||||
|
||||
const struct ccmode_siv *ccaes_siv_encrypt_mode(void);
|
||||
const struct ccmode_siv *ccaes_siv_decrypt_mode(void);
|
||||
|
||||
#endif /* _CORECRYPTO_CCAES_H_ */
|
97
include/corecrypto/ccasn1.h
Normal file
97
include/corecrypto/ccasn1.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* ccasn1.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 11/16/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCASN1_H_
|
||||
#define _CORECRYPTO_CCASN1_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ASN.1 types for on the fly ASN.1 BER/DER encoding/decoding. Don't use
|
||||
these with the ccder interface, use the CCDER_ types instead. */
|
||||
enum {
|
||||
CCASN1_EOL = 0x00,
|
||||
CCASN1_BOOLEAN = 0x01,
|
||||
CCASN1_INTEGER = 0x02,
|
||||
CCASN1_BIT_STRING = 0x03,
|
||||
CCASN1_OCTET_STRING = 0x04,
|
||||
CCASN1_NULL = 0x05,
|
||||
CCASN1_OBJECT_IDENTIFIER = 0x06,
|
||||
CCASN1_OBJECT_DESCRIPTOR = 0x07,
|
||||
/* External or instance-of 0x08 */
|
||||
CCASN1_REAL = 0x09,
|
||||
CCASN1_ENUMERATED = 0x0a,
|
||||
CCASN1_EMBEDDED_PDV = 0x0b,
|
||||
CCASN1_UTF8_STRING = 0x0c,
|
||||
/* 0x0d */
|
||||
/* 0x0e */
|
||||
/* 0x0f */
|
||||
CCASN1_SEQUENCE = 0x10,
|
||||
CCASN1_SET = 0x11,
|
||||
CCASN1_NUMERIC_STRING = 0x12,
|
||||
CCASN1_PRINTABLE_STRING = 0x13,
|
||||
CCASN1_T61_STRING = 0x14,
|
||||
CCASN1_VIDEOTEX_STRING = 0x15,
|
||||
CCASN1_IA5_STRING = 0x16,
|
||||
CCASN1_UTC_TIME = 0x17,
|
||||
CCASN1_GENERALIZED_TIME = 0x18,
|
||||
CCASN1_GRAPHIC_STRING = 0x19,
|
||||
CCASN1_VISIBLE_STRING = 0x1a,
|
||||
CCASN1_GENERAL_STRING = 0x1b,
|
||||
CCASN1_UNIVERSAL_STRING = 0x1c,
|
||||
/* 0x1d */
|
||||
CCASN1_BMP_STRING = 0x1e,
|
||||
CCASN1_HIGH_TAG_NUMBER = 0x1f,
|
||||
CCASN1_TELETEX_STRING = CCASN1_T61_STRING,
|
||||
|
||||
CCASN1_TAG_MASK = 0xff,
|
||||
CCASN1_TAGNUM_MASK = 0x1f,
|
||||
|
||||
CCASN1_METHOD_MASK = 0x20,
|
||||
CCASN1_PRIMITIVE = 0x00,
|
||||
CCASN1_CONSTRUCTED = 0x20,
|
||||
|
||||
CCASN1_CLASS_MASK = 0xc0,
|
||||
CCASN1_UNIVERSAL = 0x00,
|
||||
CCASN1_APPLICATION = 0x40,
|
||||
CCASN1_CONTEXT_SPECIFIC = 0x80,
|
||||
CCASN1_PRIVATE = 0xc0,
|
||||
|
||||
CCASN1_CONSTRUCTED_SET = CCASN1_SET | CCASN1_CONSTRUCTED,
|
||||
CCASN1_CONSTRUCTED_SEQUENCE = CCASN1_SEQUENCE | CCASN1_CONSTRUCTED,
|
||||
};
|
||||
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
typedef union {
|
||||
const unsigned char * oid;
|
||||
} __attribute__((transparent_union)) ccoid_t;
|
||||
#define CCOID(x) ((x).oid)
|
||||
#else
|
||||
typedef const unsigned char * ccoid_t;
|
||||
#define CCOID(oid) (oid)
|
||||
#endif
|
||||
|
||||
/* Returns *der iff *der points to a DER encoded oid that fits within *der_len. */
|
||||
ccoid_t ccoid_for_der(size_t *der_len, const uint8_t **der);
|
||||
|
||||
/* Returns the size of an oid including it's tag and length. */
|
||||
CC_INLINE CC_PURE CC_NONNULL_TU((1))
|
||||
size_t ccoid_size(ccoid_t oid) {
|
||||
return 2 + CCOID(oid)[1];
|
||||
}
|
||||
|
||||
CC_INLINE CC_PURE CC_NONNULL((1)) CC_NONNULL((2))
|
||||
bool ccoid_equal(ccoid_t oid1, ccoid_t oid2) {
|
||||
return (ccoid_size(oid1) == ccoid_size(oid2)
|
||||
&& memcmp(CCOID(oid1), CCOID(oid2), ccoid_size(oid1))== 0);
|
||||
}
|
||||
|
||||
#endif /* _CORECRYPTO_CCASN1_H_ */
|
92
include/corecrypto/cccmac.h
Normal file
92
include/corecrypto/cccmac.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* cccmac.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 11/07/2013
|
||||
*
|
||||
* Copyright (c) 2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_cccmac_H_
|
||||
#define _CORECRYPTO_cccmac_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <corecrypto/ccmode.h>
|
||||
#include <corecrypto/ccaes.h>
|
||||
|
||||
#define CMAC_BLOCKSIZE 16
|
||||
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
struct cccmac_ctx {
|
||||
uint8_t b[8];
|
||||
} CC_ALIGNED(8);
|
||||
|
||||
typedef struct cccmac_ctx_hdr {
|
||||
uint8_t k1[16];
|
||||
uint8_t k2[16];
|
||||
uint8_t ctx[8];
|
||||
} CC_ALIGNED(8) cccmac_ctx_hdr;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct cccmac_ctx *b;
|
||||
cccmac_ctx_hdr *hdr;
|
||||
} cccmac_ctx_t __attribute__((transparent_union));
|
||||
#define cccmac_hdr_size sizeof(struct cccmac_ctx_hdr)
|
||||
|
||||
#else
|
||||
|
||||
struct cccmac_ctx {
|
||||
uint8_t k1[16];
|
||||
uint8_t k2[16];
|
||||
uint8_t ctx[8];
|
||||
} CC_ALIGNED(8);// cccmac_ctx_hdr;
|
||||
|
||||
typedef struct cccmac_ctx* cccmac_ctx_t;
|
||||
|
||||
#define cccmac_hdr_size sizeof(struct cccmac_ctx)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define cccmac_iv_size(_mode_) ((_mode_)->block_size)
|
||||
#define cccmac_cbc_size(_mode_) ((_mode_)->size)
|
||||
|
||||
#define cccmac_ctx_size(_mode_) (cccmac_hdr_size + cccmac_iv_size(_mode_) + cccmac_cbc_size(_mode_))
|
||||
#define cccmac_ctx_n(_mode_) ccn_nof_size(cccmac_ctx_size(_mode_))
|
||||
|
||||
#define cccmac_mode_decl(_mode_, _name_) cc_ctx_decl(struct cccmac_ctx, cccmac_ctx_size(_mode_), _name_)
|
||||
#define cccmac_mode_clear(_mode_, _name_) cc_clear(cccmac_ctx_size(_mode_), _name_)
|
||||
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
/* Return a cccbc_ctx * which can be accesed with the macros in ccmode.h */
|
||||
#define cccmac_mode_ctx_start(_mode_, HC) (((HC).hdr)->ctx)
|
||||
#define CCCMAC_HDR(HC) (((cccmac_ctx_t)(HC)).hdr)
|
||||
#else
|
||||
/* Return a cccbc_ctx * which can be accesed with the macros in ccmode.h */
|
||||
#define cccmac_mode_ctx_start(_mode_, HC) (HC->ctx)
|
||||
#define CCCMAC_HDR(HC) (HC)
|
||||
#endif
|
||||
|
||||
#define cccmac_mode_sym_ctx(_mode_, HC) (cccbc_ctx *)(cccmac_mode_ctx_start(_mode_, HC))
|
||||
#define cccmac_mode_iv(_mode_, HC) (cccbc_iv *)(cccmac_mode_ctx_start(_mode_, HC)+cccmac_cbc_size(_mode_))
|
||||
#define cccmac_k1(HC) (CCCMAC_HDR(HC)->k1)
|
||||
#define cccmac_k2(HC) (CCCMAC_HDR(HC)->k2)
|
||||
|
||||
void cccmac_init(const struct ccmode_cbc *cbc, cccmac_ctx_t ctx, const void *key);
|
||||
|
||||
|
||||
void cccmac_block_update(const struct ccmode_cbc *cbc, cccmac_ctx_t cmac,
|
||||
size_t nblocks, const void *data);
|
||||
|
||||
|
||||
void cccmac_final(const struct ccmode_cbc *cbc, cccmac_ctx_t ctx,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
void cccmac(const struct ccmode_cbc *cbc, const void *key,
|
||||
size_t data_len, const void *data,
|
||||
void *mac);
|
||||
|
||||
|
||||
#endif /* _CORECRYPTO_cccmac_H_ */
|
323
include/corecrypto/ccder.h
Normal file
323
include/corecrypto/ccder.h
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* ccder.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 03/14/2012
|
||||
*
|
||||
* Copyright (c) 2012,2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCDER_H_
|
||||
#define _CORECRYPTO_CCDER_H_
|
||||
|
||||
#include <corecrypto/ccasn1.h>
|
||||
#include <corecrypto/ccn.h>
|
||||
|
||||
#define CCDER_MULTIBYTE_TAGS 1
|
||||
|
||||
#ifdef CCDER_MULTIBYTE_TAGS
|
||||
#if defined(_MSC_VER)
|
||||
//TODO related to rdar://problem/24868013
|
||||
typedef int ccder_tag; //MSVC forces enums to be ints
|
||||
#else
|
||||
typedef unsigned long ccder_tag;
|
||||
#endif
|
||||
#else
|
||||
typedef uint8_t ccder_tag;
|
||||
#endif
|
||||
|
||||
/* DER types to be used with ccder_decode and ccder_encode functions. */
|
||||
enum {
|
||||
CCDER_EOL = CCASN1_EOL,
|
||||
CCDER_BOOLEAN = CCASN1_BOOLEAN,
|
||||
CCDER_INTEGER = CCASN1_INTEGER,
|
||||
CCDER_BIT_STRING = CCASN1_BIT_STRING,
|
||||
CCDER_OCTET_STRING = CCASN1_OCTET_STRING,
|
||||
CCDER_NULL = CCASN1_NULL,
|
||||
CCDER_OBJECT_IDENTIFIER = CCASN1_OBJECT_IDENTIFIER,
|
||||
CCDER_OBJECT_DESCRIPTOR = CCASN1_OBJECT_DESCRIPTOR,
|
||||
/* External or instance-of 0x08 */
|
||||
CCDER_REAL = CCASN1_REAL,
|
||||
CCDER_ENUMERATED = CCASN1_ENUMERATED,
|
||||
CCDER_EMBEDDED_PDV = CCASN1_EMBEDDED_PDV,
|
||||
CCDER_UTF8_STRING = CCASN1_UTF8_STRING,
|
||||
/* 0x0d */
|
||||
/* 0x0e */
|
||||
/* 0x0f */
|
||||
CCDER_SEQUENCE = CCASN1_SEQUENCE,
|
||||
CCDER_SET = CCASN1_SET,
|
||||
CCDER_NUMERIC_STRING = CCASN1_NUMERIC_STRING,
|
||||
CCDER_PRINTABLE_STRING = CCASN1_PRINTABLE_STRING,
|
||||
CCDER_T61_STRING = CCASN1_T61_STRING,
|
||||
CCDER_VIDEOTEX_STRING = CCASN1_VIDEOTEX_STRING,
|
||||
CCDER_IA5_STRING = CCASN1_IA5_STRING,
|
||||
CCDER_UTC_TIME = CCASN1_UTC_TIME,
|
||||
CCDER_GENERALIZED_TIME = CCASN1_GENERALIZED_TIME,
|
||||
CCDER_GRAPHIC_STRING = CCASN1_GRAPHIC_STRING,
|
||||
CCDER_VISIBLE_STRING = CCASN1_VISIBLE_STRING,
|
||||
CCDER_GENERAL_STRING = CCASN1_GENERAL_STRING,
|
||||
CCDER_UNIVERSAL_STRING = CCASN1_UNIVERSAL_STRING,
|
||||
/* 0x1d */
|
||||
CCDER_BMP_STRING = CCASN1_BMP_STRING,
|
||||
CCDER_HIGH_TAG_NUMBER = CCASN1_HIGH_TAG_NUMBER,
|
||||
CCDER_TELETEX_STRING = CCDER_T61_STRING,
|
||||
|
||||
#ifdef CCDER_MULTIBYTE_TAGS
|
||||
CCDER_TAG_MASK = ((ccder_tag)~0),
|
||||
CCDER_TAGNUM_MASK = ((ccder_tag)~((ccder_tag)7 << (sizeof(ccder_tag) * 8 - 3))),
|
||||
|
||||
CCDER_METHOD_MASK = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
|
||||
CCDER_PRIMITIVE = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 3)),
|
||||
CCDER_CONSTRUCTED = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
|
||||
|
||||
CCDER_CLASS_MASK = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
|
||||
CCDER_UNIVERSAL = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 2)),
|
||||
CCDER_APPLICATION = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 2)),
|
||||
CCDER_CONTEXT_SPECIFIC = ((ccder_tag)2 << (sizeof(ccder_tag) * 8 - 2)),
|
||||
CCDER_PRIVATE = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
|
||||
#else
|
||||
CCDER_TAG_MASK = CCASN1_TAG_MASK,
|
||||
CCDER_TAGNUM_MASK = CCASN1_TAGNUM_MASK,
|
||||
|
||||
CCDER_METHOD_MASK = CCASN1_METHOD_MASK,
|
||||
CCDER_PRIMITIVE = CCASN1_PRIMITIVE,
|
||||
CCDER_CONSTRUCTED = CCASN1_CONSTRUCTED,
|
||||
|
||||
CCDER_CLASS_MASK = CCASN1_CLASS_MASK,
|
||||
CCDER_UNIVERSAL = CCASN1_UNIVERSAL,
|
||||
CCDER_APPLICATION = CCASN1_APPLICATION,
|
||||
CCDER_CONTEXT_SPECIFIC = CCASN1_CONTEXT_SPECIFIC,
|
||||
CCDER_PRIVATE = CCASN1_PRIVATE,
|
||||
#endif
|
||||
CCDER_CONSTRUCTED_SET = CCDER_SET | CCDER_CONSTRUCTED,
|
||||
CCDER_CONSTRUCTED_SEQUENCE = CCDER_SEQUENCE | CCDER_CONSTRUCTED,
|
||||
};
|
||||
|
||||
// MARK: ccder_sizeof_ functions
|
||||
|
||||
/* Returns the size of an asn1 encoded item of length l in bytes. */
|
||||
CC_CONST
|
||||
size_t ccder_sizeof(ccder_tag tag, size_t len);
|
||||
|
||||
CC_PURE
|
||||
size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag,
|
||||
cc_size n, const cc_unit *s);
|
||||
|
||||
CC_PURE
|
||||
size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag,
|
||||
cc_size n, const cc_unit *s);
|
||||
|
||||
CC_CONST
|
||||
size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag,
|
||||
size_t s_size);
|
||||
CC_CONST
|
||||
size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag, uint64_t value);
|
||||
|
||||
CC_PURE
|
||||
size_t ccder_sizeof_integer(cc_size n, const cc_unit *s);
|
||||
|
||||
CC_CONST
|
||||
size_t ccder_sizeof_len(size_t len);
|
||||
|
||||
CC_PURE
|
||||
size_t ccder_sizeof_octet_string(cc_size n, const cc_unit *s);
|
||||
|
||||
CC_PURE
|
||||
size_t ccder_sizeof_oid(ccoid_t oid);
|
||||
|
||||
CC_CONST
|
||||
size_t ccder_sizeof_raw_octet_string(size_t s_size);
|
||||
|
||||
CC_CONST
|
||||
size_t ccder_sizeof_tag(ccder_tag tag);
|
||||
|
||||
CC_CONST
|
||||
size_t ccder_sizeof_uint64(uint64_t value);
|
||||
|
||||
// MARK: ccder_encode_ functions.
|
||||
|
||||
/* Encode a tag backwards, der_end should point to one byte past the end of
|
||||
destination for the tag, returns a pointer to the first byte of the tag.
|
||||
Returns NULL if there is an encoding error. */
|
||||
CC_NONNULL2
|
||||
uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
/* Returns a pointer to the start of the len field. returns NULL if there
|
||||
is an encoding error. */
|
||||
CC_NONNULL2
|
||||
uint8_t *
|
||||
ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
/* der_end should point to the first byte of the content of this der item. */
|
||||
CC_NONNULL3
|
||||
uint8_t *
|
||||
ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
CC_PURE CC_NONNULL2
|
||||
uint8_t *
|
||||
ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
/* Encode the tag and length of a constructed object. der is the lower
|
||||
bound, der_end is one byte paste where we want to write the length and
|
||||
body_end is one byte past the end of the body of the der object we are
|
||||
encoding the tag and length of. */
|
||||
CC_NONNULL((2, 3))
|
||||
uint8_t *
|
||||
ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
/* Encodes oid into der and returns
|
||||
der + ccder_sizeof_oid(oid). */
|
||||
CC_NONNULL_TU((1)) CC_NONNULL2
|
||||
uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((3, 4))
|
||||
uint8_t *ccder_encode_implicit_integer(ccder_tag implicit_tag,
|
||||
cc_size n, const cc_unit *s,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((2, 3))
|
||||
uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
CC_NONNULL3
|
||||
uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag,
|
||||
uint64_t value,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
CC_NONNULL2
|
||||
uint8_t *ccder_encode_uint64(uint64_t value,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((3, 4))
|
||||
uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag,
|
||||
cc_size n, const cc_unit *s,
|
||||
const uint8_t *der,
|
||||
uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((2, 3))
|
||||
uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((3, 4))
|
||||
uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag,
|
||||
size_t s_size, const uint8_t *s,
|
||||
const uint8_t *der,
|
||||
uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((2, 3))
|
||||
uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
size_t ccder_encode_eckey_size(size_t priv_size, ccoid_t oid, size_t pub_size);
|
||||
|
||||
CC_NONNULL2 CC_NONNULL5 CC_NONNULL6 CC_NONNULL7
|
||||
uint8_t *ccder_encode_eckey(size_t priv_size, const uint8_t *priv_key,
|
||||
ccoid_t oid,
|
||||
size_t pub_size, const uint8_t *pub_key,
|
||||
uint8_t *der, uint8_t *der_end);
|
||||
|
||||
/* ccder_encode_body COPIES the body into the der.
|
||||
It's inefficient – especially when you already have to convert to get to
|
||||
the form for the body.
|
||||
see encode integer for the right way to unify conversion and insertion */
|
||||
CC_NONNULL3
|
||||
uint8_t *
|
||||
ccder_encode_body(size_t size, const uint8_t* body,
|
||||
const uint8_t *der, uint8_t *der_end);
|
||||
|
||||
// MARK: ccder_decode_ functions.
|
||||
|
||||
/* Returns a pointer to the start of the length field, and returns the decoded tag in tag.
|
||||
returns NULL if there is a decoding error. */
|
||||
CC_NONNULL((1, 3))
|
||||
const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((1, 3))
|
||||
const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
/* Returns a pointer to the start of the der object, and returns the length in len.
|
||||
returns NULL if there is a decoding error. */
|
||||
CC_NONNULL((2, 4))
|
||||
const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((2, 4))
|
||||
const uint8_t *
|
||||
ccder_decode_constructed_tl(ccder_tag expected_tag, const uint8_t **body_end,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((1, 3))
|
||||
const uint8_t *
|
||||
ccder_decode_sequence_tl(const uint8_t **body_end,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
/*!
|
||||
@function ccder_decode_uint_n
|
||||
@abstract length in cc_unit of a der unsigned integer after skipping the leading zeroes
|
||||
|
||||
@param der Beginning of input DER buffer
|
||||
@param der_end End of input DER buffer
|
||||
@param n Output the number of cc_unit required to represent the number
|
||||
|
||||
@result First byte after the parsed integer or
|
||||
NULL if the integer is not valid (negative) or reach der_end when reading the integer
|
||||
*/
|
||||
|
||||
CC_NONNULL((3))
|
||||
const uint8_t *ccder_decode_uint_n(cc_size *n,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
/*!
|
||||
@function ccder_decode_uint
|
||||
@abstract Represent in cc_unit a der unsigned integer after skipping the leading zeroes
|
||||
|
||||
@param der Beginning of input DER buffer
|
||||
@param der_end End of input DER buffer
|
||||
@param n Number of cc_unit allocated for r
|
||||
@param r Allocated array of cc_unit to copy the integer into.
|
||||
|
||||
@result First byte after the parsed integer or
|
||||
NULL if the integer is not valid (negative)
|
||||
reach der_end when reading the integer
|
||||
n cc_unit is not enough to represent the integer
|
||||
*/
|
||||
CC_NONNULL((4))
|
||||
const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((3))
|
||||
const uint8_t *ccder_decode_uint64(uint64_t* r,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
/* Decode SEQUENCE { r, s -- (unsigned)integer } in der into r and s.
|
||||
Returns NULL on decode errors, returns pointer just past the end of the
|
||||
sequence of integers otherwise. */
|
||||
CC_NONNULL((2, 3, 5))
|
||||
const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
CC_NONNULL_TU((1)) CC_NONNULL((3))
|
||||
const uint8_t *ccder_decode_oid(ccoid_t *oidp,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
CC_NONNULL((1,2,4))
|
||||
const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string,
|
||||
size_t *bit_length,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
CC_NONNULL_TU((4)) CC_NONNULL((1,2,3,5,6,8))
|
||||
const uint8_t *ccder_decode_eckey(uint64_t *version,
|
||||
size_t *priv_size, const uint8_t **priv_key,
|
||||
ccoid_t *oid,
|
||||
size_t *pub_size, const uint8_t **pub_key,
|
||||
const uint8_t *der, const uint8_t *der_end);
|
||||
|
||||
#define CC_EC_OID_SECP192R1 {((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x01")}
|
||||
#define CC_EC_OID_SECP256R1 {((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07")}
|
||||
#define CC_EC_OID_SECP224R1 {((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x21")}
|
||||
#define CC_EC_OID_SECP384R1 {((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x22")}
|
||||
#define CC_EC_OID_SECP521R1 {((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x23")}
|
||||
|
||||
|
||||
#endif /* _CORECRYPTO_CCDER_H_ */
|
68
include/corecrypto/ccdes.h
Normal file
68
include/corecrypto/ccdes.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ccdes.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/20/2010
|
||||
*
|
||||
* Copyright (c) 2010,2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CORECRYPTO_CCDES_H_
|
||||
#define _CORECRYPTO_CCDES_H_
|
||||
|
||||
#include <corecrypto/ccmode.h>
|
||||
|
||||
#define CCDES_BLOCK_SIZE 8
|
||||
#define CCDES_KEY_SIZE 8
|
||||
|
||||
extern const struct ccmode_ecb ccdes_ltc_ecb_decrypt_mode;
|
||||
extern const struct ccmode_ecb ccdes_ltc_ecb_encrypt_mode;
|
||||
|
||||
extern const struct ccmode_ecb ccdes3_ltc_ecb_decrypt_mode;
|
||||
extern const struct ccmode_ecb ccdes3_ltc_ecb_encrypt_mode;
|
||||
extern const struct ccmode_ecb ccdes168_ltc_ecb_encrypt_mode;
|
||||
|
||||
const struct ccmode_ecb *ccdes_ecb_decrypt_mode(void);
|
||||
const struct ccmode_ecb *ccdes_ecb_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_cbc *ccdes_cbc_decrypt_mode(void);
|
||||
const struct ccmode_cbc *ccdes_cbc_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_cfb *ccdes_cfb_decrypt_mode(void);
|
||||
const struct ccmode_cfb *ccdes_cfb_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_cfb8 *ccdes_cfb8_decrypt_mode(void);
|
||||
const struct ccmode_cfb8 *ccdes_cfb8_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_ctr *ccdes_ctr_crypt_mode(void);
|
||||
|
||||
const struct ccmode_ofb *ccdes_ofb_crypt_mode(void);
|
||||
|
||||
|
||||
const struct ccmode_ecb *ccdes3_ecb_decrypt_mode(void);
|
||||
const struct ccmode_ecb *ccdes3_ecb_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_cbc *ccdes3_cbc_decrypt_mode(void);
|
||||
const struct ccmode_cbc *ccdes3_cbc_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_cfb *ccdes3_cfb_decrypt_mode(void);
|
||||
const struct ccmode_cfb *ccdes3_cfb_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_cfb8 *ccdes3_cfb8_decrypt_mode(void);
|
||||
const struct ccmode_cfb8 *ccdes3_cfb8_encrypt_mode(void);
|
||||
|
||||
const struct ccmode_ctr *ccdes3_ctr_crypt_mode(void);
|
||||
|
||||
const struct ccmode_ofb *ccdes3_ofb_crypt_mode(void);
|
||||
|
||||
int ccdes_key_is_weak( void *key, size_t length);
|
||||
void ccdes_key_set_odd_parity(void *key, size_t length);
|
||||
|
||||
uint32_t
|
||||
ccdes_cbc_cksum(void *in, void *out, size_t length,
|
||||
void *key, size_t keylen, void *ivec);
|
||||
|
||||
|
||||
#endif /* _CORECRYPTO_CCDES_H_ */
|
@ -1,142 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lubos Dolezel
|
||||
* ccdigest.h
|
||||
* corecrypto
|
||||
*
|
||||
* This file is part of Darling CoreCrypto.
|
||||
* Created on 11/30/2010
|
||||
*
|
||||
* Darling is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCDIGEST_H
|
||||
#define _CORECRYPTO_CCDIGEST_H
|
||||
#ifndef _CORECRYPTO_CCDIGEST_H_
|
||||
#define _CORECRYPTO_CCDIGEST_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <corecrypto/ccn.h>
|
||||
|
||||
struct ccdigest_ctx // followed by struct ccdigest_state
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t u8;
|
||||
uint32_t u32;
|
||||
uint64_t u64; // holds nbits (amount of bits compressed in total)
|
||||
cc_unit ccn; // also 64bits
|
||||
} state;
|
||||
}
|
||||
__attribute((aligned(8)));
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct ccdigest_ctx *hdr;
|
||||
} ccdigest_ctx_t
|
||||
__attribute__((transparent_union));
|
||||
/* To malloc a digest context for a given di, use malloc(ccdigest_di_size(di))
|
||||
and assign the result to a pointer to a struct ccdigest_ctx. */
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
struct ccdigest_ctx {
|
||||
union {
|
||||
uint8_t u8;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
cc_unit ccn;
|
||||
} state;
|
||||
} CC_ALIGNED(8);
|
||||
|
||||
struct ccdigest_state
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t u8;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
cc_unit ccn; // also 64bits
|
||||
} state;
|
||||
}
|
||||
__attribute((aligned(8)));
|
||||
// ccdigest_state is followed by block_size of buffer
|
||||
typedef union {
|
||||
struct ccdigest_ctx *hdr;
|
||||
} ccdigest_ctx_t __attribute__((transparent_union));
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct ccdigest_state *hdr;
|
||||
struct ccdigest_ctx *_ctx;
|
||||
ccdigest_ctx_t _ctxt;
|
||||
} ccdigest_state_t
|
||||
__attribute__((transparent_union));
|
||||
struct ccdigest_state {
|
||||
union {
|
||||
uint8_t u8;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
cc_unit ccn;
|
||||
} state;
|
||||
} CC_ALIGNED(8);
|
||||
|
||||
struct ccdigest_info
|
||||
{
|
||||
unsigned long output_size;
|
||||
unsigned long state_size;
|
||||
unsigned long block_size;
|
||||
unsigned long oid_size;
|
||||
unsigned char* oid;
|
||||
const void* initial_state;
|
||||
void(*compress)(ccdigest_state_t state, unsigned long nblocks, const void* data);
|
||||
void(*final)(const struct ccdigest_info* di, ccdigest_ctx_t ctx, unsigned char* digest);
|
||||
typedef union {
|
||||
struct ccdigest_state *hdr;
|
||||
struct ccdigest_ctx *_ctx;
|
||||
ccdigest_ctx_t _ctxt;
|
||||
} ccdigest_state_t __attribute__((transparent_union));
|
||||
#else //=======================================================
|
||||
struct ccdigest_ctx {
|
||||
union {
|
||||
uint8_t u8;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
cc_unit ccn;
|
||||
} state;
|
||||
} CC_ALIGNED(8);
|
||||
|
||||
typedef struct ccdigest_ctx *ccdigest_ctx_t ;
|
||||
|
||||
struct ccdigest_state {
|
||||
union {
|
||||
uint8_t u8;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
cc_unit ccn;
|
||||
} state;
|
||||
} CC_ALIGNED(8);
|
||||
|
||||
typedef struct ccdigest_state *ccdigest_state_t;
|
||||
#endif //=======================================================
|
||||
|
||||
|
||||
struct ccdigest_info {
|
||||
size_t output_size;
|
||||
size_t state_size;
|
||||
size_t block_size;
|
||||
size_t oid_size;
|
||||
const unsigned char *oid;
|
||||
const void *initial_state;
|
||||
void(*compress)(ccdigest_state_t state, size_t nblocks,
|
||||
const void *data);
|
||||
void(*final)(const struct ccdigest_info *di, ccdigest_ctx_t ctx,
|
||||
unsigned char *digest);
|
||||
};
|
||||
|
||||
/* Return sizeof a ccdigest_ctx for a given size_t _state_size_ and
|
||||
size_t _block_size_. */
|
||||
#define ccdigest_ctx_size(_state_size_, _block_size_) ((_state_size_) + sizeof(uint64_t) + (_block_size_) + sizeof(unsigned int))
|
||||
/* Return sizeof a ccdigest_ctx for a given struct ccdigest_info *_di_. */
|
||||
#define ccdigest_di_size(_di_) (ccdigest_ctx_size((_di_)->state_size, (_di_)->block_size))
|
||||
|
||||
void ccdigest_init(const struct ccdigest_info* di, ccdigest_ctx_t ctx);
|
||||
|
||||
// Submit data to the compress function, block by block
|
||||
// Incomplete blocks are saved at ccdigest_data(), amount of data stored within is set at ccdigest_num()
|
||||
void ccdigest_update(const struct ccdigest_info* di, ccdigest_ctx_t ctx, unsigned long len, const void* data);
|
||||
|
||||
void ccdigest(const struct ccdigest_info* di, unsigned long len, const void* data, void* digest);
|
||||
|
||||
int ccdigest_test(const struct ccdigest_info* di, unsigned long len, const void* data, const void* digest);
|
||||
|
||||
int ccdigest_test_chunk(const struct ccdigest_info* di, unsigned long len, const void* data, const void *digest, unsigned long chunk);
|
||||
|
||||
struct ccdigest_vector
|
||||
{
|
||||
unsigned long len;
|
||||
const void* message;
|
||||
const void* digest;
|
||||
};
|
||||
|
||||
int ccdigest_test_vector(const struct ccdigest_info* di, const struct ccdigest_vector* v);
|
||||
int ccdigest_test_chunk_vector(const struct ccdigest_info* di, const struct ccdigest_vector* v, unsigned long chunk);
|
||||
|
||||
#define ccdigest_ctx_size(statesize_, block_size) ((statesize_) + sizeof(uint64_t) + (block_size) + sizeof(unsigned int))
|
||||
#define ccdigest_di_size(di) (ccdigest_ctx_size((di)->state_size, (di)->block_size))
|
||||
|
||||
#define ccdigest_ctx_decl(statesize_, block_size, name) cc_ctx_decl(struct ccdigest_ctx, ccdigest_ctx_size(statesize_, block_size), name)
|
||||
#define ccdigest_ctx_clear(statesize_, block_size, name) cc_clear(ccdigest_ctx_size(statesize_, block_size), name)
|
||||
|
||||
#define ccdigest_di_decl(di, name) cc_ctx_decl(struct ccdigest_ctx, ccdigest_di_size(di), name)
|
||||
#define ccdigest_di_clear(di, name) cc_clear(ccdigest_di_size(di), name)
|
||||
|
||||
#define ccdigest_state(di, ctx) ((struct ccdigest_state*)((ctx).hdr + 1))
|
||||
#define ccdigest_state_u8(di, ctx) ccdigest_u8(ccdigest_state((di), (ctx)))
|
||||
#define ccdigest_state_u32(di, ctx) ccdigest_u32(ccdigest_state((di), (ctx)))
|
||||
#define ccdigest_state_u64(di, ctx) ccdigest_u64(ccdigest_state((di), (ctx)))
|
||||
#define ccdigest_state_ccn(di, ctx) ccdigest_ccn(ccdigest_state((di), (ctx)))
|
||||
#define ccdigest_nbits(di, ctx) ((ccdigest_ctx_t)(ctx)).hdr->state.u64
|
||||
|
||||
#define ccdigest_data(di, ctx) (&((ccdigest_ctx_t)(ctx)).hdr->state.u8 + (di)->state_size + sizeof(uint64_t))
|
||||
#define ccdigest_num(di, ctx) (*((unsigned int *)(&((ccdigest_ctx_t)(ctx)).hdr->state.u8 + (di)->state_size + sizeof(uint64_t) + (di)->block_size)))
|
||||
|
||||
static inline uint8_t* ccdigest_u8(ccdigest_state_t state) { return &state.hdr->state.u8; }
|
||||
static inline uint32_t* ccdigest_u32(ccdigest_state_t state) { return &state.hdr->state.u32; }
|
||||
static inline uint64_t* ccdigest_u64(ccdigest_state_t state) { return &state.hdr->state.u64; }
|
||||
static inline cc_unit* ccdigest_ccn(ccdigest_state_t state) { return &state.hdr->state.ccn; }
|
||||
#define ccdigest_final(di, ctx, digest) (di)->final(di, ctx, digest)
|
||||
|
||||
#define ccdigest_copy_state(di, dst, src) memcpy(dst, src, (di)->state_size)
|
||||
|
||||
#define CC_DIGEST_OID_MD2 (const unsigned char*)("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x02")
|
||||
#define CC_DIGEST_OID_MD4 (const unsigned char*)("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x04")
|
||||
#define CC_DIGEST_OID_MD5 (const unsigned char*)("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x05")
|
||||
#define CC_DIGEST_OID_SHA1 (const unsigned char*)("\x06\x05\x2b\x0e\x03\x02\x1a")
|
||||
#define CC_DIGEST_OID_SHA224 (const unsigned char*)("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04")
|
||||
#define CC_DIGEST_OID_SHA256 (const unsigned char*)("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01")
|
||||
#define CC_DIGEST_OID_SHA384 (const unsigned char*)("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02")
|
||||
#define CC_DIGEST_OID_SHA512 (const unsigned char*)("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03")
|
||||
#define CC_DIGEST_OID_RMD128 (const unsigned char*)("\x06\x06\x28\xCF\x06\x03\x00\x32")
|
||||
#define CC_DIGEST_OID_RMD160 (const unsigned char*)("\x06\x05\x2B\x24\x03\x02\x01")
|
||||
#define CC_DIGEST_OID_RMD256 (const unsigned char*)("\x06\x05\x2B\x24\x03\x02\x03")
|
||||
#define CC_DIGEST_OID_RMD320 NULL
|
||||
|
||||
/* Declare a ccdigest_ctx for a given size_t _state_size_ and
|
||||
size_t _block_size_, named _name_. Can be used in structs or on the
|
||||
stack. */
|
||||
#define ccdigest_ctx_decl(_state_size_, _block_size_, _name_) cc_ctx_decl(struct ccdigest_ctx, ccdigest_ctx_size(_state_size_, _block_size_), _name_)
|
||||
#define ccdigest_ctx_clear(_state_size_, _block_size_, _name_) cc_clear(ccdigest_ctx_size(_state_size_, _block_size_), _name_)
|
||||
/* Declare a ccdigest_ctx for a given size_t _state_size_ and
|
||||
size_t _block_size_, named _name_. Can be used on the stack. */
|
||||
#define ccdigest_di_decl(_di_, _name_) cc_ctx_decl(struct ccdigest_ctx, ccdigest_di_size(_di_), _name_)
|
||||
#define ccdigest_di_clear(_di_, _name_) cc_clear(ccdigest_di_size(_di_), _name_)
|
||||
|
||||
/* Digest context field accessors. Consider the implementation private. */
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
#define ccdigest_state(_di_, _ctx_) ((struct ccdigest_state *)(&((ccdigest_ctx_t)(_ctx_)).hdr->state.u8 + sizeof(uint64_t)))
|
||||
#else
|
||||
#define ccdigest_state(_di_, _ctx_) ((struct ccdigest_state *)(&((ccdigest_ctx_t)(_ctx_))->state.u8 + sizeof(uint64_t)))
|
||||
#endif
|
||||
|
||||
#define ccdigest_state_u8(_di_, _ctx_) ccdigest_u8(ccdigest_state((_di_), (_ctx_)))
|
||||
#define ccdigest_state_u32(_di_, _ctx_) ccdigest_u32(ccdigest_state((_di_), (_ctx_)))
|
||||
#define ccdigest_state_u64(_di_, _ctx_) ccdigest_u64(ccdigest_state((_di_), (_ctx_)))
|
||||
#define ccdigest_state_ccn(_di_, _ctx_) ccdigest_ccn(ccdigest_state((_di_), (_ctx_)))
|
||||
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
#define ccdigest_nbits(_di_, _ctx_) (((uint64_t *)(&((ccdigest_ctx_t)(_ctx_)).hdr->state.u8))[0])
|
||||
#define ccdigest_data(_di_, _ctx_) (&((ccdigest_ctx_t)(_ctx_)).hdr->state.u8 + (_di_)->state_size + sizeof(uint64_t))
|
||||
#define ccdigest_num(_di_, _ctx_) (((unsigned int *)(&((ccdigest_ctx_t)(_ctx_)).hdr->state.u8 + (_di_)->state_size + sizeof(uint64_t) + (_di_)->block_size))[0])
|
||||
#else
|
||||
#define ccdigest_nbits(_di_, _ctx_) (((uint64_t *)(&((ccdigest_ctx_t)(_ctx_))->state.u8))[0])
|
||||
#define ccdigest_data(_di_, _ctx_) (&((ccdigest_ctx_t)(_ctx_))->state.u8 + (_di_)->state_size + sizeof(uint64_t))
|
||||
#define ccdigest_num(_di_, _ctx_) (((unsigned int *)(&((ccdigest_ctx_t)(_ctx_))->state.u8 + (_di_)->state_size + sizeof(uint64_t) + (_di_)->block_size))[0])
|
||||
#endif
|
||||
|
||||
#if CORECRYPTO_USE_TRANSPARENT_UNION
|
||||
/* Digest state field accessors. Consider the implementation private. */
|
||||
#define ccdigest_u8(_state_) (&((ccdigest_state_t)(_state_)).hdr->state.u8)
|
||||
#define ccdigest_u32(_state_) (&((ccdigest_state_t)(_state_)).hdr->state.u32)
|
||||
#define ccdigest_u64(_state_) (&((ccdigest_state_t)(_state_)).hdr->state.u64)
|
||||
#define ccdigest_ccn(_state_) (&((ccdigest_state_t)(_state_)).hdr->state.ccn)
|
||||
#else
|
||||
/* Digest state field accessors. Consider the implementation private. */
|
||||
#define ccdigest_u8(_state_) (&((ccdigest_state_t)(_state_))->state.u8)
|
||||
#define ccdigest_u32(_state_) (&((ccdigest_state_t)(_state_))->state.u32)
|
||||
#define ccdigest_u64(_state_) (&((ccdigest_state_t)(_state_))->state.u64)
|
||||
#define ccdigest_ccn(_state_) (&((ccdigest_state_t)(_state_))->state.ccn)
|
||||
#endif
|
||||
|
||||
/* We could just use memcpy instead of this special macro, but this allows us
|
||||
to use the optimized ccn_set() assembly routine if we have one, which for
|
||||
32 bit arm is about 200% quicker than generic memcpy(). */
|
||||
#if CCN_SET_ASM && CCN_UNIT_SIZE <= 4
|
||||
#define ccdigest_copy_state(_di_, _dst_, _src_) ccn_set((_di_)->state_size / CCN_UNIT_SIZE, _dst_, _src_)
|
||||
#else
|
||||
#define ccdigest_copy_state(_di_, _dst_, _src_) CC_MEMCPY(_dst_, _src_, (_di_)->state_size)
|
||||
#endif
|
||||
|
||||
void ccdigest_init(const struct ccdigest_info *di, ccdigest_ctx_t ctx);
|
||||
void ccdigest_update(const struct ccdigest_info *di, ccdigest_ctx_t ctx,
|
||||
size_t len, const void *data);
|
||||
|
||||
CC_INLINE
|
||||
void ccdigest_final(const struct ccdigest_info *di, ccdigest_ctx_t ctx, unsigned char *digest)
|
||||
{
|
||||
di->final(di,ctx,digest);
|
||||
}
|
||||
|
||||
void ccdigest(const struct ccdigest_info *di, size_t len,
|
||||
const void *data, void *digest);
|
||||
|
||||
/* test functions */
|
||||
int ccdigest_test(const struct ccdigest_info *di, size_t len,
|
||||
const void *data, const void *digest);
|
||||
|
||||
int ccdigest_test_chunk(const struct ccdigest_info *di, size_t len,
|
||||
const void *data, const void *digest, size_t chunk);
|
||||
|
||||
struct ccdigest_vector {
|
||||
size_t len;
|
||||
const void *message;
|
||||
const void *digest;
|
||||
};
|
||||
|
||||
int ccdigest_test_vector(const struct ccdigest_info *di, const struct ccdigest_vector *v);
|
||||
int ccdigest_test_chunk_vector(const struct ccdigest_info *di, const struct ccdigest_vector *v, size_t chunk);
|
||||
|
||||
|
||||
#define OID_DEF(_VALUE_) ((const unsigned char *)_VALUE_)
|
||||
|
||||
#define CC_DIGEST_OID_MD2 OID_DEF("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x02")
|
||||
#define CC_DIGEST_OID_MD4 OID_DEF("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x04")
|
||||
#define CC_DIGEST_OID_MD5 OID_DEF("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x05")
|
||||
#define CC_DIGEST_OID_SHA1 OID_DEF("\x06\x05\x2b\x0e\x03\x02\x1a")
|
||||
#define CC_DIGEST_OID_SHA224 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04")
|
||||
#define CC_DIGEST_OID_SHA256 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01")
|
||||
#define CC_DIGEST_OID_SHA384 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02")
|
||||
#define CC_DIGEST_OID_SHA512 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03")
|
||||
#define CC_DIGEST_OID_RMD128 OID_DEF("\x06\x06\x28\xCF\x06\x03\x00\x32")
|
||||
#define CC_DIGEST_OID_RMD160 OID_DEF("\x06\x05\x2B\x24\x03\x02\x01")
|
||||
#define CC_DIGEST_OID_RMD256 OID_DEF("\x06\x05\x2B\x24\x03\x02\x03")
|
||||
#define CC_DIGEST_OID_RMD320 OID_DEF(NULL)
|
||||
|
||||
#endif /* _CORECRYPTO_CCDIGEST_H_ */
|
||||
|
36
include/corecrypto/ccdigest_priv.h
Normal file
36
include/corecrypto/ccdigest_priv.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ccdigest_priv.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/07/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCDIGEST_PRIV_H_
|
||||
#define _CORECRYPTO_CCDIGEST_PRIV_H_
|
||||
|
||||
#include <corecrypto/ccdigest.h>
|
||||
#include <corecrypto/ccasn1.h>
|
||||
|
||||
void ccdigest_final_common(const struct ccdigest_info *di,
|
||||
ccdigest_ctx_t ctx, void *digest);
|
||||
void ccdigest_final_64be(const struct ccdigest_info *di, ccdigest_ctx_t,
|
||||
unsigned char *digest);
|
||||
void ccdigest_final_64le(const struct ccdigest_info *di, ccdigest_ctx_t,
|
||||
unsigned char *digest);
|
||||
|
||||
CC_INLINE CC_NONNULL_TU((1))
|
||||
bool ccdigest_oid_equal(const struct ccdigest_info *di, ccoid_t oid) {
|
||||
if(di->oid == NULL && CCOID(oid) == NULL) return true;
|
||||
if(di->oid == NULL || CCOID(oid) == NULL) return false;
|
||||
return ccoid_equal(di->oid, oid);
|
||||
}
|
||||
|
||||
typedef const struct ccdigest_info *(ccdigest_lookup)(ccoid_t oid);
|
||||
|
||||
#include <stdarg.h>
|
||||
const struct ccdigest_info *ccdigest_oid_lookup(ccoid_t oid, ...);
|
||||
|
||||
#endif /* _CORECRYPTO_CCDIGEST_PRIV_H_ */
|
128
include/corecrypto/ccdrbg.h
Normal file
128
include/corecrypto/ccdrbg.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* ccdrbg.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 08/17/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
@header corecrypto/ccdrbg.h
|
||||
@abstract The functions provided in ccdrbg.h implement high-level accessors
|
||||
to cryptographically secure random numbers.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCDRBG_H_
|
||||
#define _CORECRYPTO_CCDRBG_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <corecrypto/ccdrbg_impl.h>
|
||||
|
||||
/* error codes */
|
||||
#define CCDRBG_STATUS_OK 0
|
||||
#define CCDRBG_STATUS_ERROR (-1)
|
||||
#define CCDRBG_STATUS_NEED_RESEED (-2)
|
||||
#define CCDRBG_STATUS_PARAM_ERROR (-3)
|
||||
// If this value is returned, the caller must abort or panic the process for security reasons.
|
||||
// for example in the case of catastrophic error in
|
||||
// http://csrc.nist.gov/publications/drafts/800-90/sp800_90a_r1_draft.pdf
|
||||
// ccdrbg calls abort() or panic(), if they are available in the system.
|
||||
#define CCDRBG_STATUS_ABORT (-4)
|
||||
/*
|
||||
* The maximum length of the entropy_input, additional_input (max_additional_input_length) , personalization string
|
||||
* (max_personalization_string_length) and max_number_of_bits_per_request are implementation dependent
|
||||
* but shall fit in a 32 bit register and be be less than or equal to the specified maximum length for the
|
||||
* selected DRBG mechanism (NIST 800-90A Section 10).
|
||||
*/
|
||||
|
||||
#define CCDRBG_MAX_ENTROPY_SIZE ((uint32_t)1<<16)
|
||||
#define CCDRBG_MAX_ADDITIONALINPUT_SIZE ((uint32_t)1<<16)
|
||||
#define CCDRBG_MAX_PSINPUT_SIZE ((uint32_t)1<<16)
|
||||
#define CCDRBG_MAX_REQUEST_SIZE ((uint32_t)1<<16) //this is the the absolute maximum in NIST 800-90A
|
||||
#define CCDRBG_RESEED_INTERVAL ((uint64_t)1<<30) // must be able to fit the NIST maximum of 2^48
|
||||
|
||||
|
||||
/*
|
||||
* The entropyLength is forced to be greater or equal than the security strength.
|
||||
* Nonce is not forced. It either needs to have 0.5*security strength entropy. Or, a vale that is repeated
|
||||
* less than a 0.5*security strength bit random string.
|
||||
* see below or NIST 800-90A for the definition of security strength
|
||||
*/
|
||||
|
||||
CC_INLINE int ccdrbg_init(const struct ccdrbg_info *info,
|
||||
struct ccdrbg_state *drbg,
|
||||
size_t entropyLength, const void* entropy,
|
||||
size_t nonceLength, const void* nonce,
|
||||
size_t psLength, const void* ps)
|
||||
{
|
||||
return info->init(info, drbg, entropyLength, entropy, nonceLength, nonce, psLength, ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* The entropyLength is forced to be greater or equal than the security strength.
|
||||
*/
|
||||
CC_INLINE int ccdrbg_reseed(const struct ccdrbg_info *info,
|
||||
struct ccdrbg_state *drbg,
|
||||
size_t entropyLength, const void *entropy,
|
||||
size_t additionalLength, const void *additional)
|
||||
{
|
||||
return info->reseed(drbg, entropyLength, entropy, additionalLength, additional);
|
||||
}
|
||||
|
||||
|
||||
CC_INLINE int ccdrbg_generate(const struct ccdrbg_info *info,
|
||||
struct ccdrbg_state *drbg,
|
||||
size_t dataOutLength, void *dataOut,
|
||||
size_t additionalLength, const void *additional)
|
||||
{
|
||||
return info->generate(drbg, dataOutLength, dataOut, additionalLength, additional);
|
||||
}
|
||||
|
||||
CC_INLINE void ccdrbg_done(const struct ccdrbg_info *info,
|
||||
struct ccdrbg_state *drbg)
|
||||
{
|
||||
info->done(drbg);
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccdrbg_context_size(const struct ccdrbg_info *drbg)
|
||||
{
|
||||
return drbg->size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NIST SP 800-90 CTR_DRBG
|
||||
* the mximum security strengh of drbg equals to the block size of the corresponding ECB.
|
||||
*/
|
||||
struct ccdrbg_nistctr_custom {
|
||||
const struct ccmode_ecb *ecb;
|
||||
size_t keylen;
|
||||
int strictFIPS;
|
||||
int use_df;
|
||||
};
|
||||
|
||||
void ccdrbg_factory_nistctr(struct ccdrbg_info *info, const struct ccdrbg_nistctr_custom *custom);
|
||||
|
||||
/*
|
||||
* NIST SP 800-90 HMAC_DRBG
|
||||
* the maximum security strengh of drbg is half of output size of the input hash function and it internally is limited to 256 bits
|
||||
*/
|
||||
extern struct ccdrbg_info ccdrbg_nistdigest_info;
|
||||
|
||||
struct ccdrbg_nisthmac_custom {
|
||||
const struct ccdigest_info *di;
|
||||
int strictFIPS;
|
||||
};
|
||||
|
||||
void ccdrbg_factory_nisthmac(struct ccdrbg_info *info, const struct ccdrbg_nisthmac_custom *custom);
|
||||
|
||||
|
||||
/*
|
||||
* Dummy DRBG
|
||||
*/
|
||||
extern struct ccdrbg_info ccdrbg_dummy_info;
|
||||
|
||||
#endif /* _CORECRYPTO_CCDRBG_H_ */
|
69
include/corecrypto/ccdrbg_impl.h
Normal file
69
include/corecrypto/ccdrbg_impl.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ccdrbg_impl.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 01/03/2012
|
||||
*
|
||||
* Copyright (c) 2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCDRBG_IMPL_H_
|
||||
#define _CORECRYPTO_CCDRBG_IMPL_H_
|
||||
|
||||
/* opaque drbg structure */
|
||||
struct ccdrbg_state;
|
||||
|
||||
struct ccdrbg_info {
|
||||
/*! Size of the DRBG state in bytes **/
|
||||
size_t size;
|
||||
|
||||
/*! Instantiate the PRNG
|
||||
@param prng The PRNG state
|
||||
@param entropylen Length of entropy
|
||||
@param entropy Entropy bytes
|
||||
@param inlen Length of additional input
|
||||
@param in Additional input bytes
|
||||
@return 0 if successful
|
||||
*/
|
||||
int (*init)(const struct ccdrbg_info *info, struct ccdrbg_state *drbg,
|
||||
size_t entropyLength, const void* entropy,
|
||||
size_t nonceLength, const void* nonce,
|
||||
size_t psLength, const void* ps);
|
||||
|
||||
/*! Add entropy to the PRNG
|
||||
@param prng The PRNG state
|
||||
@param entropylen Length of entropy
|
||||
@param entropy Entropy bytes
|
||||
@param inlen Length of additional input
|
||||
@param in Additional input bytes
|
||||
@return 0 if successful
|
||||
*/
|
||||
int (*reseed)(struct ccdrbg_state *prng,
|
||||
size_t entropylen, const void *entropy,
|
||||
size_t inlen, const void *in);
|
||||
|
||||
/*! Read from the PRNG in a FIPS Testing compliant manor
|
||||
@param prng The PRNG state to read from
|
||||
@param out [out] Where to store the data
|
||||
@param outlen Length of data desired (octets)
|
||||
@param inlen Length of additional input
|
||||
@param in Additional input bytes
|
||||
@return 0 if successfull
|
||||
*/
|
||||
int (*generate)(struct ccdrbg_state *prng,
|
||||
size_t outlen, void *out,
|
||||
size_t inlen, const void *in);
|
||||
|
||||
/*! Terminate a PRNG state
|
||||
@param prng The PRNG state to terminate
|
||||
*/
|
||||
void (*done)(struct ccdrbg_state *prng);
|
||||
|
||||
/** private parameters */
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _CORECRYPTO_CCDRBG_IMPL_H_
|
84
include/corecrypto/cchmac.h
Normal file
84
include/corecrypto/cchmac.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* cchmac.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/07/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCHMAC_H_
|
||||
#define _CORECRYPTO_CCHMAC_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <corecrypto/ccdigest.h>
|
||||
|
||||
/* An hmac_ctx_t is normally allocated as an array of these. */
|
||||
struct cchmac_ctx {
|
||||
uint8_t b[8];
|
||||
} CC_ALIGNED(8);
|
||||
|
||||
typedef union {
|
||||
struct cchmac_ctx *hdr;
|
||||
ccdigest_ctx_t digest;
|
||||
} cchmac_ctx_t __attribute__((transparent_union));
|
||||
|
||||
#define cchmac_ctx_size(STATE_SIZE, BLOCK_SIZE) (ccdigest_ctx_size(STATE_SIZE, BLOCK_SIZE) + (STATE_SIZE))
|
||||
#define cchmac_di_size(_di_) (cchmac_ctx_size((_di_)->state_size, (_di_)->block_size))
|
||||
|
||||
#define cchmac_ctx_n(STATE_SIZE, BLOCK_SIZE) ccn_nof_size(cchmac_ctx_size((STATE_SIZE), (BLOCK_SIZE)))
|
||||
|
||||
#define cchmac_ctx_decl(STATE_SIZE, BLOCK_SIZE, _name_) cc_ctx_decl(struct cchmac_ctx, cchmac_ctx_size(STATE_SIZE, BLOCK_SIZE), _name_)
|
||||
#define cchmac_ctx_clear(STATE_SIZE, BLOCK_SIZE, _name_) cc_clear(cchmac_ctx_size(STATE_SIZE, BLOCK_SIZE), _name_)
|
||||
#define cchmac_di_decl(_di_, _name_) cchmac_ctx_decl((_di_)->state_size, (_di_)->block_size, _name_)
|
||||
#define cchmac_di_clear(_di_, _name_) cchmac_ctx_clear((_di_)->state_size, (_di_)->block_size, _name_)
|
||||
|
||||
/* Return a ccdigest_ctx_t which can be accesed with the macros in ccdigest.h */
|
||||
#define cchmac_digest_ctx(_di_, HC) (((cchmac_ctx_t)(HC)).digest)
|
||||
|
||||
/* Accesors for ostate fields, this is all cchmac_ctx_t adds to the ccdigest_ctx_t. */
|
||||
#define cchmac_ostate(_di_, HC) ((struct ccdigest_state *)(((cchmac_ctx_t)(HC)).hdr->b + ccdigest_di_size(_di_)))
|
||||
#define cchmac_ostate8(_di_, HC) (ccdigest_u8(cchmac_ostate(_di_, HC)))
|
||||
#define cchmac_ostate32(_di_, HC) (ccdigest_u32(cchmac_ostate(_di_, HC)))
|
||||
#define cchmac_ostate64(_di_, HC) (ccdigest_u64(cchmac_ostate(_di_, HC)))
|
||||
#define cchmac_ostateccn(_di_, HC) (ccdigest_ccn(cchmac_ostate(_di_, HC)))
|
||||
|
||||
/* Convenience accessors for ccdigest_ctx_t fields. */
|
||||
#define cchmac_istate(_di_, HC) ccdigest_state(_di_, ((cchmac_ctx_t)(HC)).digest)
|
||||
#define cchmac_istate8(_di_, HC) ccdigest_u8(cchmac_istate(_di_, HC))
|
||||
#define cchmac_istate32(_di_, HC) ccdigest_u32(cchmac_istate(_di_, HC))
|
||||
#define cchmac_istate64(_di_, HC) ccdigest_u64(cchmac_istate(_di_, HC))
|
||||
#define cchmac_istateccn(_di_, HC) ccdigest_ccn(cchmac_istate(_di_, HC))
|
||||
#define cchmac_data(_di_, HC) ccdigest_data(_di_, ((cchmac_ctx_t)(HC)).digest)
|
||||
#define cchmac_num(_di_, HC) ccdigest_num(_di_, ((cchmac_ctx_t)(HC)).digest)
|
||||
#define cchmac_nbits(_di_, HC) ccdigest_nbits(_di_, ((cchmac_ctx_t)(HC)).digest)
|
||||
|
||||
void cchmac_init(const struct ccdigest_info *di, cchmac_ctx_t ctx,
|
||||
size_t key_len, const void *key);
|
||||
void cchmac_update(const struct ccdigest_info *di, cchmac_ctx_t ctx,
|
||||
size_t data_len, const void *data);
|
||||
void cchmac_final(const struct ccdigest_info *di, cchmac_ctx_t ctx,
|
||||
unsigned char *mac);
|
||||
|
||||
void cchmac(const struct ccdigest_info *di, size_t key_len,
|
||||
const void *key, size_t data_len, const void *data,
|
||||
unsigned char *mac);
|
||||
|
||||
/* Test functions */
|
||||
|
||||
struct cchmac_test_input {
|
||||
const struct ccdigest_info *di;
|
||||
size_t key_len;
|
||||
const void *key;
|
||||
size_t data_len;
|
||||
const void *data;
|
||||
size_t mac_len;
|
||||
const void *expected_mac;
|
||||
};
|
||||
|
||||
int cchmac_test(const struct cchmac_test_input *input);
|
||||
int cchmac_test_chunks(const struct cchmac_test_input *input, size_t chunk_size);
|
||||
|
||||
|
||||
#endif /* _CORECRYPTO_CCHMAC_H_ */
|
@ -1,35 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lubos Dolezel
|
||||
* ccmd5.h
|
||||
* corecrypto
|
||||
*
|
||||
* This file is part of Darling CoreCrypto.
|
||||
* Created on 12/06/2010
|
||||
*
|
||||
* Darling is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright (c) 2010,2011,2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCMD5_H
|
||||
#define _CORECRYPTO_CCMD5_H
|
||||
#ifndef _CORECRYPTO_CCMD5_H_
|
||||
#define _CORECRYPTO_CCMD5_H_
|
||||
|
||||
#include <corecrypto/ccdigest.h>
|
||||
|
||||
#define CCMD5_BLOCK_SIZE 64
|
||||
#define CCMD5_OUTPUT_SIZE 16
|
||||
#define CCMD5_STATE_SIZE 88
|
||||
#define CCMD5_STATE_SIZE 16
|
||||
|
||||
extern const uint32_t ccmd5_initial_state[4];
|
||||
|
||||
extern const struct ccdigest_info ccmd5_ltc_di;
|
||||
/* Selector */
|
||||
const struct ccdigest_info *ccmd5_di(void);
|
||||
|
||||
#endif
|
||||
/* Implementations */
|
||||
extern const struct ccdigest_info ccmd5_ltc_di;
|
||||
|
||||
#endif /* _CORECRYPTO_CCMD5_H_ */
|
||||
|
561
include/corecrypto/ccmode.h
Normal file
561
include/corecrypto/ccmode.h
Normal file
@ -0,0 +1,561 @@
|
||||
/*
|
||||
* ccmode.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/07/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCMODE_H_
|
||||
#define _CORECRYPTO_CCMODE_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <corecrypto/ccmode_impl.h>
|
||||
#include <corecrypto/ccmode_siv.h>
|
||||
|
||||
/* ECB mode. */
|
||||
|
||||
/* Declare a ecb key named _name_. Pass the size field of a struct ccmode_ecb
|
||||
for _size_. */
|
||||
#define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl(ccecb_ctx, _size_, _name_)
|
||||
#define ccecb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccecb_block_size(const struct ccmode_ecb *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx,
|
||||
size_t key_len, const void *key)
|
||||
{
|
||||
mode->init(mode, ctx, key_len, key);
|
||||
}
|
||||
|
||||
CC_INLINE void ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx,
|
||||
size_t nblocks, const void *in, void *out)
|
||||
{
|
||||
mode->ecb(ctx, nblocks, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE void ccecb_one_shot(const struct ccmode_ecb *mode,
|
||||
size_t key_len, const void *key,
|
||||
size_t nblocks, const void *in, void *out)
|
||||
{
|
||||
ccecb_ctx_decl(mode->size, ctx);
|
||||
mode->init(mode, ctx, key_len, key);
|
||||
mode->ecb(ctx, nblocks, in, out);
|
||||
ccecb_ctx_clear(mode->size, ctx);
|
||||
}
|
||||
|
||||
/* CBC mode. */
|
||||
|
||||
/* The CBC interface changed due to rdar://11468135. This macros is to indicate
|
||||
to client which CBC API is implemented. Clients can support old versions of
|
||||
corecrypto at build time using this.
|
||||
*/
|
||||
#define __CC_HAS_FIX_FOR_11468135__ 1
|
||||
|
||||
/* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
|
||||
for _size_. */
|
||||
#define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
|
||||
#define cccbc_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
/* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
|
||||
struct ccmode_cbc for _size_. */
|
||||
#define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
|
||||
#define cccbc_iv_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
/* Actual symmetric algorithm implementation can provide you one of these.
|
||||
|
||||
Alternatively you can create a ccmode_cbc instance from any ccmode_ecb
|
||||
cipher. To do so, statically initialize a struct ccmode_cbc using the
|
||||
CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros.
|
||||
Alternatively you can dynamically initialize a struct ccmode_cbc
|
||||
ccmode_factory_cbc_decrypt() or ccmode_factory_cbc_encrypt(). */
|
||||
|
||||
CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t cccbc_block_size(const struct ccmode_cbc *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
|
||||
size_t key_len, const void *key)
|
||||
{
|
||||
mode->init(mode, ctx, key_len, key);
|
||||
}
|
||||
|
||||
CC_INLINE void cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx,
|
||||
const void *iv)
|
||||
{
|
||||
if (iv)
|
||||
cc_copy(mode->block_size, iv_ctx, iv);
|
||||
else
|
||||
cc_zero(mode->block_size, iv_ctx);
|
||||
}
|
||||
|
||||
CC_INLINE void cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
|
||||
cccbc_iv *iv, size_t nblocks,
|
||||
const void *in, void *out)
|
||||
{
|
||||
mode->cbc(ctx, iv, nblocks, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE void cccbc_one_shot(const struct ccmode_cbc *mode,
|
||||
size_t key_len, const void *key,
|
||||
const void *iv, size_t nblocks,
|
||||
const void *in, void *out)
|
||||
{
|
||||
cccbc_ctx_decl(mode->size, ctx);
|
||||
cccbc_iv_decl(mode->block_size, iv_ctx);
|
||||
mode->init(mode, ctx, key_len, key);
|
||||
if (iv)
|
||||
cccbc_set_iv(mode, iv_ctx, iv);
|
||||
else
|
||||
cc_zero(mode->block_size, iv_ctx);
|
||||
mode->cbc(ctx, iv_ctx, nblocks, in, out);
|
||||
cccbc_ctx_clear(mode->size, ctx);
|
||||
}
|
||||
|
||||
/* CFB mode. */
|
||||
|
||||
/* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
|
||||
for _size_. */
|
||||
#define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
|
||||
#define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t cccfb_block_size(const struct ccmode_cfb *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
|
||||
size_t key_len, const void *key,
|
||||
const void *iv)
|
||||
{
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
}
|
||||
|
||||
CC_INLINE void cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
mode->cfb(ctx, nbytes, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE void cccfb_one_shot(const struct ccmode_cfb *mode,
|
||||
size_t key_len, const void *key, const void *iv,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
cccfb_ctx_decl(mode->size, ctx);
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
mode->cfb(ctx, nbytes, in, out);
|
||||
cccfb_ctx_clear(mode->size, ctx);
|
||||
}
|
||||
|
||||
/* CFB8 mode. */
|
||||
|
||||
/* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
|
||||
for _size_. */
|
||||
#define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
|
||||
#define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t cccfb8_block_size(const struct ccmode_cfb8 *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *iv)
|
||||
{
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
}
|
||||
|
||||
CC_INLINE void cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
mode->cfb8(ctx, nbytes, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE void cccfb8_one_shot(const struct ccmode_cfb8 *mode,
|
||||
size_t key_len, const void *key, const void *iv,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
cccfb8_ctx_decl(mode->size, ctx);
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
mode->cfb8(ctx, nbytes, in, out);
|
||||
cccfb8_ctx_clear(mode->size, ctx);
|
||||
}
|
||||
|
||||
/* CTR mode. */
|
||||
|
||||
/* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
|
||||
for _size_. */
|
||||
#define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
|
||||
#define ccctr_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
/* This is Integer Counter Mode: The IV is the initial value of the counter
|
||||
that is incremented by 1 for each new block. Use the mode flags to select
|
||||
if the IV/Counter is stored in big or little endian. */
|
||||
|
||||
CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccctr_block_size(const struct ccmode_ctr *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *iv)
|
||||
{
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
}
|
||||
|
||||
CC_INLINE void ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
mode->ctr(ctx, nbytes, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE void ccctr_one_shot(const struct ccmode_ctr *mode,
|
||||
size_t key_len, const void *key, const void *iv,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
ccctr_ctx_decl(mode->size, ctx);
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
mode->ctr(ctx, nbytes, in, out);
|
||||
ccctr_ctx_clear(mode->size, ctx);
|
||||
}
|
||||
|
||||
|
||||
/* OFB mode. */
|
||||
|
||||
/* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
|
||||
for _size_. */
|
||||
#define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
|
||||
#define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccofb_block_size(const struct ccmode_ofb *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *iv)
|
||||
{
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
}
|
||||
|
||||
CC_INLINE void ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
mode->ofb(ctx, nbytes, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE void ccofb_one_shot(const struct ccmode_ofb *mode,
|
||||
size_t key_len, const void *key, const void *iv,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
ccofb_ctx_decl(mode->size, ctx);
|
||||
mode->init(mode, ctx, key_len, key, iv);
|
||||
mode->ofb(ctx, nbytes, in, out);
|
||||
ccofb_ctx_clear(mode->size, ctx);
|
||||
}
|
||||
|
||||
/* Authenticated cipher modes. */
|
||||
|
||||
/* XTS mode. */
|
||||
|
||||
/* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
|
||||
for _size_. */
|
||||
#define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
|
||||
#define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
/* Declare a xts tweak named _name_. Pass the tweak_size field of a
|
||||
struct ccmode_xts for _size_. */
|
||||
#define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
|
||||
#define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
/* Actual symmetric algorithm implementation can provide you one of these.
|
||||
|
||||
Alternatively you can create a ccmode_xts instance from any ccmode_ecb
|
||||
cipher. To do so, statically initialize a struct ccmode_xts using the
|
||||
CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
|
||||
you can dynamically initialize a struct ccmode_xts
|
||||
ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
|
||||
|
||||
/* NOTE that xts mode does not do cts padding. It's really an xex mode.
|
||||
If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
|
||||
functions. Also note that xts only works for ecb modes with a block_size
|
||||
of 16. */
|
||||
|
||||
CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccxts_block_size(const struct ccmode_xts *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx,
|
||||
size_t key_len, const void *key,
|
||||
const void *tweak_key)
|
||||
{
|
||||
mode->init(mode, ctx, key_len, key, tweak_key);
|
||||
}
|
||||
|
||||
CC_INLINE void ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx,
|
||||
ccxts_tweak *tweak, const void *iv)
|
||||
{
|
||||
mode->set_tweak(ctx, tweak, iv);
|
||||
}
|
||||
|
||||
CC_INLINE void *ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx,
|
||||
ccxts_tweak *tweak, size_t nblocks, const void *in, void *out)
|
||||
{
|
||||
return mode->xts(ctx, tweak, nblocks, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE void ccxts_one_shot(const struct ccmode_xts *mode,
|
||||
size_t key_len, const void *key,
|
||||
const void *tweak_key, const void *iv,
|
||||
size_t nblocks, const void *in, void *out)
|
||||
{
|
||||
ccxts_ctx_decl(mode->size, ctx);
|
||||
ccxts_tweak_decl(mode->tweak_size, tweak);
|
||||
mode->init(mode, ctx, key_len, key, tweak_key);
|
||||
mode->set_tweak(ctx, tweak, iv);
|
||||
mode->xts(ctx, tweak, nblocks, in, out);
|
||||
ccxts_ctx_clear(mode->size, ctx);
|
||||
ccxts_tweak_clear(mode->tweak_size, tweak);
|
||||
}
|
||||
|
||||
/* GCM mode. */
|
||||
|
||||
/* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
|
||||
for _size_. */
|
||||
#define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_)
|
||||
#define ccgcm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccgcm_block_size(const struct ccmode_gcm *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE int ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
|
||||
size_t key_len, const void *key)
|
||||
{
|
||||
return mode->init(mode, ctx, key_len, key);
|
||||
}
|
||||
|
||||
CC_INLINE int ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
|
||||
size_t iv_size, const void *iv)
|
||||
{
|
||||
return mode->set_iv(ctx, iv_size, iv);
|
||||
}
|
||||
|
||||
// add Additional authenticated data (AAD)
|
||||
CC_INLINE int ccgcm_aad(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
|
||||
size_t nbytes, const void *additional_data)
|
||||
{
|
||||
return mode->gmac(ctx, nbytes, additional_data);
|
||||
}
|
||||
|
||||
CC_INLINE int ccgcm_gmac(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
|
||||
size_t nbytes, const void *in)
|
||||
{
|
||||
return mode->gmac(ctx, nbytes, in);
|
||||
}
|
||||
|
||||
// encrypt or decrypt
|
||||
CC_INLINE int ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
return mode->gcm(ctx, nbytes, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE int ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
|
||||
size_t tag_size, void *tag)
|
||||
{
|
||||
return mode->finalize(ctx, tag_size, tag);
|
||||
}
|
||||
|
||||
CC_INLINE int ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
|
||||
{
|
||||
return mode->reset(ctx);
|
||||
}
|
||||
|
||||
|
||||
int ccgcm_one_shot(const struct ccmode_gcm *mode,
|
||||
size_t key_len, const void *key,
|
||||
size_t iv_len, const void *iv,
|
||||
size_t adata_len, const void *adata,
|
||||
size_t nbytes, const void *in, void *out,
|
||||
size_t tag_len, void *tag);
|
||||
|
||||
//do not call ccgcm_one_shot_legacy() in any new application
|
||||
int ccgcm_one_shot_legacy(const struct ccmode_gcm *mode,
|
||||
size_t key_len, const void *key,
|
||||
size_t iv_len, const void *iv,
|
||||
size_t adata_len, const void *adata,
|
||||
size_t nbytes, const void *in, void *out,
|
||||
size_t tag_len, void *tag);
|
||||
|
||||
|
||||
/* CCM */
|
||||
|
||||
#define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
|
||||
#define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
/* Declare a ccm nonce named _name_. Pass the mode->nonce_ctx_size for _size_. */
|
||||
#define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl(ccccm_nonce, _size_, _name_)
|
||||
#define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
|
||||
CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccccm_block_size(const struct ccmode_ccm *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE int ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx,
|
||||
size_t key_len, const void *key)
|
||||
{
|
||||
return mode->init(mode, ctx, key_len, key);
|
||||
}
|
||||
|
||||
CC_INLINE int ccccm_set_iv(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
|
||||
size_t nonce_len, const void *nonce,
|
||||
size_t mac_size, size_t auth_len, size_t data_len)
|
||||
{
|
||||
return mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
|
||||
}
|
||||
|
||||
CC_INLINE int ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
|
||||
size_t nbytes, const void *in)
|
||||
{
|
||||
return mode->cbcmac(ctx, nonce_ctx, nbytes, in);
|
||||
}
|
||||
|
||||
CC_INLINE int ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
|
||||
size_t nbytes, const void *in, void *out)
|
||||
{
|
||||
return mode->ccm(ctx, nonce_ctx, nbytes, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE int ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
|
||||
void *mac)
|
||||
{
|
||||
return mode->finalize(ctx, nonce_ctx, mac);
|
||||
}
|
||||
|
||||
CC_INLINE int ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
|
||||
{
|
||||
return mode->reset(ctx, nonce_ctx);
|
||||
}
|
||||
|
||||
|
||||
CC_INLINE int ccccm_one_shot(const struct ccmode_ccm *mode,
|
||||
size_t key_len, const void *key,
|
||||
unsigned nonce_len, const void *nonce,
|
||||
size_t nbytes, const void *in, void *out,
|
||||
unsigned adata_len, const void* adata,
|
||||
unsigned mac_size, void *mac)
|
||||
{
|
||||
int rc=0;
|
||||
ccccm_ctx_decl(mode->size, ctx);
|
||||
ccccm_nonce_decl(mode->nonce_size, nonce_ctx);
|
||||
rc = mode->init(mode, ctx, key_len, key);
|
||||
if(rc==0) rc=mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
|
||||
if(rc==0) rc=mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
|
||||
if(rc==0) rc=mode->ccm(ctx, nonce_ctx, nbytes, in, out);
|
||||
if(rc==0) rc=mode->finalize(ctx, nonce_ctx, mac);
|
||||
ccccm_ctx_clear(mode->size, ctx);
|
||||
ccccm_nonce_clear(mode->size, nonce_ctx);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* OMAC mode. */
|
||||
|
||||
|
||||
/* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
|
||||
for _size_. */
|
||||
#define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
|
||||
#define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccomac_block_size(const struct ccmode_omac *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE void ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx,
|
||||
size_t tweak_len, size_t key_len, const void *key)
|
||||
{
|
||||
mode->init(mode, ctx, tweak_len, key_len, key);
|
||||
}
|
||||
|
||||
CC_INLINE int ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx,
|
||||
size_t nblocks, const void *tweak, const void *in, void *out)
|
||||
{
|
||||
return mode->omac(ctx, nblocks, tweak, in, out);
|
||||
}
|
||||
|
||||
CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
|
||||
size_t tweak_len, size_t key_len, const void *key,
|
||||
const void *tweak, size_t nblocks, const void *in, void *out)
|
||||
{
|
||||
ccomac_ctx_decl(mode->size, ctx);
|
||||
mode->init(mode, ctx, tweak_len, key_len, key);
|
||||
int result = mode->omac(ctx, nblocks, tweak, in, out);
|
||||
ccomac_ctx_clear(mode->size, ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _CORECRYPTO_CCMODE_H_ */
|
581
include/corecrypto/ccmode_factory.h
Normal file
581
include/corecrypto/ccmode_factory.h
Normal file
@ -0,0 +1,581 @@
|
||||
/*
|
||||
* ccmode_factory.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 01/21/2011
|
||||
*
|
||||
* Copyright (c) 2011,2012,2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCMODE_FACTORY_H_
|
||||
#define _CORECRYPTO_CCMODE_FACTORY_H_
|
||||
|
||||
#include <corecrypto/ccn.h> /* TODO: Remove dependency on this header. */
|
||||
#include <corecrypto/ccmode_impl.h>
|
||||
|
||||
/* Function and macros defined in this file are only to be used
|
||||
within corecrypto files.
|
||||
*/
|
||||
|
||||
/* For CBC, direction of underlying ecb is the same as the cbc direction */
|
||||
#define CCMODE_CBC_FACTORY(_cipher_, _dir_) \
|
||||
static struct ccmode_cbc cbc_##_cipher_##_##_dir_; \
|
||||
\
|
||||
const struct ccmode_cbc *cc##_cipher_##_cbc_##_dir_##_mode(void) \
|
||||
{ \
|
||||
const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_##_dir_##_mode(); \
|
||||
ccmode_factory_cbc_##_dir_(&cbc_##_cipher_##_##_dir_, ecb); \
|
||||
return &cbc_##_cipher_##_##_dir_; \
|
||||
}
|
||||
|
||||
/* For CTR, only one direction, underlying ecb is always encrypt */
|
||||
#define CCMODE_CTR_FACTORY(_cipher_) \
|
||||
static struct ccmode_ctr ctr_##_cipher_; \
|
||||
\
|
||||
const struct ccmode_ctr *cc##_cipher_##_ctr_crypt_mode(void) \
|
||||
{ \
|
||||
const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode(); \
|
||||
ccmode_factory_ctr_crypt(&ctr_##_cipher_, ecb); \
|
||||
return &ctr_##_cipher_; \
|
||||
}
|
||||
|
||||
/* OFB, same as CTR */
|
||||
#define CCMODE_OFB_FACTORY(_cipher_) \
|
||||
static struct ccmode_ofb ofb_##_cipher_; \
|
||||
\
|
||||
const struct ccmode_ofb *cc##_cipher_##_ofb_crypt_mode(void) \
|
||||
{ \
|
||||
const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode(); \
|
||||
ccmode_factory_ofb_crypt(&ofb_##_cipher_, ecb); \
|
||||
return &ofb_##_cipher_; \
|
||||
}
|
||||
|
||||
|
||||
/* For CFB, the underlying ecb operation is encrypt for both directions */
|
||||
#define CCMODE_CFB_FACTORY(_cipher_, _mode_, _dir_) \
|
||||
static struct ccmode_##_mode_ _mode_##_##_cipher_##_##_dir_; \
|
||||
\
|
||||
const struct ccmode_##_mode_ *cc##_cipher_##_##_mode_##_##_dir_##_mode(void) \
|
||||
{ \
|
||||
const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode(); \
|
||||
ccmode_factory_##_mode_##_##_dir_(&_mode_##_##_cipher_##_##_dir_, ecb); \
|
||||
return &_mode_##_##_cipher_##_##_dir_; \
|
||||
}
|
||||
|
||||
/* For GCM, same as CFB */
|
||||
#define CCMODE_GCM_FACTORY(_cipher_, _dir_) CCMODE_CFB_FACTORY(_cipher_, gcm, _dir_)
|
||||
|
||||
/* For CCM, same as CFB */
|
||||
#define CCMODE_CCM_FACTORY(_cipher_, _dir_) CCMODE_CFB_FACTORY(_cipher_, ccm, _dir_)
|
||||
|
||||
|
||||
/* Fot XTS, you always need an ecb encrypt */
|
||||
#define CCMODE_XTS_FACTORY(_cipher_ , _dir_) \
|
||||
static struct ccmode_xts xts##_cipher_##_##_dir_; \
|
||||
\
|
||||
const struct ccmode_xts *cc##_cipher_##_xts_##_dir_##_mode(void) \
|
||||
{ \
|
||||
const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_##_dir_##_mode(); \
|
||||
const struct ccmode_ecb *ecb_enc=cc##_cipher_##_ecb_encrypt_mode(); \
|
||||
\
|
||||
ccmode_factory_xts_##_dir_(&xts##_cipher_##_##_dir_, ecb, ecb_enc); \
|
||||
return &xts##_cipher_##_##_dir_; \
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* example of how to make the selection function thread safe */
|
||||
|
||||
struct ccmode_cbc cc3des_cbc_mode_encrypt;
|
||||
dispatch_once_t cc3des_mode_encrypt_init_once;
|
||||
|
||||
void cc3des_mode_encrypt_init(void *ctx) {
|
||||
struct ccmode_ecb *ecb = cc3des_ecb_encrypt_mode();
|
||||
ccmode_factory_cbc_encrypt(&cc3des_mode_encrypt, ecb);
|
||||
}
|
||||
|
||||
const struct ccmode_cbc *cc3des_cbc_encrypt_mode(void) {
|
||||
dispatch_once_f(&cc3des_mode_encrypt_init_once, NULL, cc3des_mode_encrypt_init);
|
||||
return &cc3des_mode_encrypt;
|
||||
}
|
||||
|
||||
struct ccmode_cbc cc3des_cbc_mode_encrypt = {
|
||||
.n = CC3DES_LTC_ECB_ENCRYPT_N,
|
||||
.init = ccmode_cbc_init,
|
||||
.cbc = ccmode_cbc_encrypt,
|
||||
.custom = &cc3des_ltc_ecb_encrypt
|
||||
};
|
||||
|
||||
const struct ccmode_cbc *cc3des_cbc_encrypt_mode(void) {
|
||||
return &cc3des_mode_encrypt;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void ccmode_cbc_init(const struct ccmode_cbc *cbc, cccbc_ctx *ctx,
|
||||
size_t rawkey_len, const void *rawkey);
|
||||
void ccmode_cbc_decrypt(const cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks,
|
||||
const void *in, void *out);
|
||||
void ccmode_cbc_encrypt(const cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks,
|
||||
const void *in, void *out);
|
||||
|
||||
struct _ccmode_cbc_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_cbc object for decryption. */
|
||||
#define CCMODE_FACTORY_CBC_DECRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_cbc_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = (ECB)->block_size, \
|
||||
.init = ccmode_cbc_init, \
|
||||
.cbc = ccmode_cbc_decrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use this to statically initialize a ccmode_cbc object for encryption. */
|
||||
#define CCMODE_FACTORY_CBC_ENCRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_cbc_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = (ECB)->block_size, \
|
||||
.init = ccmode_cbc_init, \
|
||||
.cbc = ccmode_cbc_encrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_cbc decrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb decrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_cbc_decrypt(struct ccmode_cbc *cbc,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_cbc encrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_cbc_encrypt(struct ccmode_cbc *cbc,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
|
||||
void ccmode_cfb_init(const struct ccmode_cfb *cfb, cccfb_ctx *ctx,
|
||||
size_t rawkey_len, const void *rawkey,
|
||||
const void *iv);
|
||||
void ccmode_cfb_decrypt(cccfb_ctx *ctx, size_t nbytes,
|
||||
const void *in, void *out);
|
||||
void ccmode_cfb_encrypt(cccfb_ctx *ctx, size_t nbytes,
|
||||
const void *in, void *out);
|
||||
struct _ccmode_cfb_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
size_t pad_len;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_cfb object for decryption. */
|
||||
#define CCMODE_FACTORY_CFB_DECRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_cfb_init, \
|
||||
.cfb = ccmode_cfb_decrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use this to statically initialize a ccmode_cfb object for encryption. */
|
||||
#define CCMODE_FACTORY_CFB_ENCRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_cfb_init, \
|
||||
.cfb = ccmode_cfb_encrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_cfb decrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_cfb_decrypt(struct ccmode_cfb *cfb,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_cfb encrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_cfb_encrypt(struct ccmode_cfb *cfb,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
void ccmode_cfb8_init(const struct ccmode_cfb8 *cfb8, cccfb8_ctx *ctx,
|
||||
size_t rawkey_len, const void *rawkey, const void *iv);
|
||||
void ccmode_cfb8_decrypt(cccfb8_ctx *ctx, size_t nbytes,
|
||||
const void *in, void *out);
|
||||
void ccmode_cfb8_encrypt(cccfb8_ctx *ctx, size_t nbytes,
|
||||
const void *in, void *out);
|
||||
|
||||
struct _ccmode_cfb8_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_cfb8 object for decryption. */
|
||||
#define CCMODE_FACTORY_CFB8_DECRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb8_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_cfb8_init, \
|
||||
.cfb8 = ccmode_cfb8_decrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use this to statically initialize a ccmode_cfb8 object for encryption. */
|
||||
#define CCMODE_FACTORY_CFB8_ENCRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb8_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_cfb8_init, \
|
||||
.cfb8 = ccmode_cfb8_encrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_cfb8 decrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb decrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_cfb8_decrypt(struct ccmode_cfb8 *cfb8,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_cfb8 encrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_cfb8_encrypt(struct ccmode_cfb8 *cfb8,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
void ccmode_ctr_init(const struct ccmode_ctr *ctr, ccctr_ctx *ctx,
|
||||
size_t rawkey_len, const void *rawkey, const void *iv);
|
||||
void ccmode_ctr_crypt(ccctr_ctx *ctx, size_t nbytes,
|
||||
const void *in, void *out);
|
||||
|
||||
struct _ccmode_ctr_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
size_t pad_len;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_ctr object for decryption. */
|
||||
#define CCMODE_FACTORY_CTR_CRYPT(ECB_ENCRYPT) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_ctr_key)) + 2 * ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_ctr_init, \
|
||||
.ctr = ccmode_ctr_crypt, \
|
||||
.custom = (ECB_ENCRYPT) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_ctr decrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_ctr_crypt(struct ccmode_ctr *ctr,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
|
||||
/* Create a gcm key from a gcm mode object.
|
||||
key must point to at least sizeof(CCMODE_GCM_KEY(ecb)) bytes of free
|
||||
storage. */
|
||||
int ccmode_gcm_init(const struct ccmode_gcm *gcm, ccgcm_ctx *ctx,
|
||||
size_t rawkey_len, const void *rawkey);
|
||||
int ccmode_gcm_set_iv(ccgcm_ctx *ctx, size_t iv_size, const void *iv);
|
||||
int ccmode_gcm_aad(ccgcm_ctx *ctx, size_t nbytes, const void *in);
|
||||
int ccmode_gcm_decrypt(ccgcm_ctx *ctx, size_t nbytes, const void *in,
|
||||
void *out);
|
||||
int ccmode_gcm_encrypt(ccgcm_ctx *ctx, size_t nbytes, const void *in,
|
||||
void *out);
|
||||
|
||||
/*!
|
||||
@function ccmode_gcm_finalize() finalizes AES-GCM call sequence
|
||||
@param key encryption or decryption key
|
||||
@param tag_size
|
||||
@param tag
|
||||
@result 0=success or non zero= error
|
||||
@discussion For decryption, the tag parameter must be the expected-tag. A secure compare is performed between the provided expected-tag and the computed-tag. If they are the same, 0 is returned. Otherwise, non zero is returned. For encryption, tag is output and provides the authentication tag.
|
||||
|
||||
*/
|
||||
int ccmode_gcm_finalize(ccgcm_ctx *key, size_t tag_size, void *tag);
|
||||
int ccmode_gcm_reset(ccgcm_ctx *key);
|
||||
|
||||
|
||||
// Here is what the structure looks like in memory
|
||||
// [ temp space | length | *ecb | *ecb_key | table | ecb_key ]
|
||||
// size of table depends on the implementation (VNG vs factory)
|
||||
struct _ccmode_gcm_key {
|
||||
// 5 blocks of temp space.
|
||||
unsigned char H[16]; /* multiplier */
|
||||
unsigned char X[16]; /* accumulator */
|
||||
unsigned char Y[16]; /* counter */
|
||||
unsigned char Y_0[16]; /* initial counter */
|
||||
unsigned char buf[16]; /* buffer for stuff */
|
||||
|
||||
// State and length
|
||||
uint32_t ivmode; /* Which mode is the IV in? */
|
||||
uint32_t state; /* state the GCM code is in */
|
||||
uint32_t buflen; /* length of data in buf */
|
||||
|
||||
uint64_t totlen; /* 64-bit counter used for IV and AAD */
|
||||
uint64_t pttotlen; /* 64-bit counter for the plaintext PT */
|
||||
|
||||
// ECB
|
||||
const struct ccmode_ecb *ecb; // ecb mode
|
||||
// Pointer to the ECB key in the buffer
|
||||
void *ecb_key; // address of the ecb_key in u, set in init function
|
||||
int encdec; //is it an encrypt or decrypt object
|
||||
|
||||
// Buffer with ECB key and H table if applicable
|
||||
unsigned char u[] __attribute__ ((aligned (16))); // ecb key + tables
|
||||
};
|
||||
|
||||
#define GCM_ECB_KEY_SIZE(ECB_ENCRYPT) \
|
||||
((5 * ccn_sizeof_size((ECB_ENCRYPT)->block_size)) \
|
||||
+ ccn_sizeof_size((ECB_ENCRYPT)->size))
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_gcm decrypt object (for
|
||||
example if it's part of a larger structure). For GCM you always pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_gcm_decrypt(struct ccmode_gcm *gcm,
|
||||
const struct ccmode_ecb *ecb_encrypt);
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_gcm encrypt object (for
|
||||
example if it's part of a larger structure). For GCM you always pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_gcm_encrypt(struct ccmode_gcm *gcm,
|
||||
const struct ccmode_ecb *ecb_encrypt);
|
||||
|
||||
|
||||
/* CCM (only NIST approved with AES) */
|
||||
int ccmode_ccm_init(const struct ccmode_ccm *ccm, ccccm_ctx *ctx,
|
||||
size_t rawkey_len, const void *rawkey);
|
||||
int ccmode_ccm_set_iv(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nonce_len, const void *nonce,
|
||||
size_t mac_size, size_t auth_len, size_t data_len);
|
||||
/* internal function */
|
||||
void ccmode_ccm_macdata(ccccm_ctx *key, ccccm_nonce *nonce_ctx, unsigned new_block, size_t nbytes, const void *in);
|
||||
/* api function - disallows only mac'd data after data to encrypt was sent */
|
||||
int ccmode_ccm_cbcmac(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in);
|
||||
/* internal function */
|
||||
void ccmode_ccm_crypt(ccccm_ctx *key, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out);
|
||||
int ccmode_ccm_decrypt(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in,
|
||||
void *out);
|
||||
int ccmode_ccm_encrypt(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in,
|
||||
void *out);
|
||||
int ccmode_ccm_finalize(ccccm_ctx *key, ccccm_nonce *nonce_ctx, void *mac);
|
||||
int ccmode_ccm_reset(ccccm_ctx *key, ccccm_nonce *nonce_ctx);
|
||||
|
||||
struct _ccmode_ccm_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
struct _ccmode_ccm_nonce {
|
||||
unsigned char A_i[16]; /* crypto block iv */
|
||||
unsigned char B_i[16]; /* mac block iv */
|
||||
unsigned char MAC[16]; /* crypted mac */
|
||||
unsigned char buf[16]; /* crypt buffer */
|
||||
|
||||
uint32_t mode; /* mode: IV -> AD -> DATA */
|
||||
uint32_t buflen; /* length of data in buf */
|
||||
uint32_t b_i_len; /* length of cbcmac data in B_i */
|
||||
|
||||
size_t nonce_size;
|
||||
size_t mac_size;
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_ccm object for decryption. */
|
||||
#define CCMODE_FACTORY_CCM_DECRYPT(ECB_ENCRYPT) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_key)) + ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \
|
||||
.nonce_size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_nonce)), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_ccm_init, \
|
||||
.set_iv = ccmode_ccm_set_iv, \
|
||||
.cbcmac = ccmode_ccm_cbcmac, \
|
||||
.ccm = ccmode_ccm_decrypt, \
|
||||
.finalize = ccmode_ccm_finalize, \
|
||||
.reset = ccmode_ccm_reset, \
|
||||
.custom = (ECB_ENCRYPT) \
|
||||
}
|
||||
|
||||
/* Use this to statically initialize a ccmode_ccm object for encryption. */
|
||||
#define CCMODE_FACTORY_CCM_ENCRYPT(ECB_ENCRYPT) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_key)) + ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \
|
||||
.nonce_size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_nonce)), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_ccm_init, \
|
||||
.set_iv = ccmode_ccm_set_iv, \
|
||||
.cbcmac = ccmode_ccm_cbcmac, \
|
||||
.ccm = ccmode_ccm_encrypt, \
|
||||
.finalize = ccmode_ccm_finalize, \
|
||||
.reset = ccmode_ccm_reset, \
|
||||
.custom = (ECB_ENCRYPT) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_ccm decrypt object (for
|
||||
example if it's part of a larger structure). For CCM you always pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
|
||||
void ccmode_factory_ccm_decrypt(struct ccmode_ccm *ccm,
|
||||
const struct ccmode_ecb *ecb_encrypt);
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_ccm encrypt object (for
|
||||
example if it's part of a larger structure). For CCM you always pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_ccm_encrypt(struct ccmode_ccm *ccm,
|
||||
const struct ccmode_ecb *ecb_encrypt);
|
||||
|
||||
|
||||
void ccmode_ofb_init(const struct ccmode_ofb *ofb, ccofb_ctx *ctx,
|
||||
size_t rawkey_len, const void *rawkey,
|
||||
const void *iv);
|
||||
void ccmode_ofb_crypt(ccofb_ctx *ctx, size_t nbytes,
|
||||
const void *in, void *out);
|
||||
|
||||
struct _ccmode_ofb_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
size_t pad_len;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_ofb object. */
|
||||
#define CCMODE_FACTORY_OFB_CRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_ofb_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = 1, \
|
||||
.init = ccmode_ofb_init, \
|
||||
.ofb = ccmode_ofb_crypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_ofb encrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_ofb_crypt(struct ccmode_ofb *ofb,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
int ccmode_omac_decrypt(ccomac_ctx *ctx, size_t nblocks,
|
||||
const void *tweak, const void *in, void *out);
|
||||
int ccmode_omac_encrypt(ccomac_ctx *ctx, size_t nblocks,
|
||||
const void *tweak, const void *in, void *out);
|
||||
|
||||
/* Create a omac key from a omac mode object. The tweak_len here
|
||||
determines how long the tweak is in bytes, for each subsequent call to
|
||||
ccmode_omac->omac().
|
||||
key must point to at least sizeof(CCMODE_OMAC_KEY(ecb)) bytes of free
|
||||
storage. */
|
||||
void ccmode_omac_init(const struct ccmode_omac *omac, ccomac_ctx *ctx,
|
||||
size_t tweak_len, size_t rawkey_len,
|
||||
const void *rawkey);
|
||||
|
||||
struct _ccmode_omac_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
size_t tweak_len;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_omac object for decryption. */
|
||||
#define CCMODE_FACTORY_OMAC_DECRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_omac_key)) + 2 * ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = (ECB)->block_size, \
|
||||
.init = ccmode_omac_init, \
|
||||
.omac = ccmode_omac_decrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use this to statically initialize a ccmode_omac object for encryption. */
|
||||
#define CCMODE_FACTORY_OMAC_ENCRYPT(ECB) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_omac_key)) + 2 * ccn_sizeof_size((ECB)->size), \
|
||||
.block_size = (ECB)->block_size, \
|
||||
.init = ccmode_omac_init, \
|
||||
.omac = ccmode_omac_encrypt, \
|
||||
.custom = (ECB) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_omac decrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb decrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_omac_decrypt(struct ccmode_omac *omac,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_omac encrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_omac_encrypt(struct ccmode_omac *omac,
|
||||
const struct ccmode_ecb *ecb);
|
||||
|
||||
|
||||
/* Function prototypes used by the macros below, do not call directly. */
|
||||
void ccmode_xts_init(const struct ccmode_xts *xts, ccxts_ctx *ctx,
|
||||
size_t key_len, const void *data_key,
|
||||
const void *tweak_key);
|
||||
void *ccmode_xts_crypt(const ccxts_ctx *ctx, ccxts_tweak *tweak,
|
||||
size_t nblocks, const void *in, void *out);
|
||||
void ccmode_xts_set_tweak(const ccxts_ctx *ctx, ccxts_tweak *tweak,
|
||||
const void *iv);
|
||||
|
||||
|
||||
struct _ccmode_xts_key {
|
||||
const struct ccmode_ecb *ecb;
|
||||
const struct ccmode_ecb *ecb_encrypt;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
struct _ccmode_xts_tweak {
|
||||
// FIPS requires that for XTS that no more that 2^20 AES blocks may be processed for any given
|
||||
// Key, Tweak Key, and tweak combination
|
||||
// the bytes_processed field in the context will accumuate the number of blocks processed and
|
||||
// will fail the encrypt/decrypt if the size is violated. This counter will be reset to 0
|
||||
// when set_tweak is called.
|
||||
size_t blocks_processed;
|
||||
cc_unit u[];
|
||||
};
|
||||
|
||||
/* Use this to statically initialize a ccmode_xts object for decryption. */
|
||||
#define CCMODE_FACTORY_XTS_DECRYPT(ECB, ECB_ENCRYPT) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_xts_key)) + 2 * ccn_sizeof_size((ECB)->size), \
|
||||
.tweak_size = ccn_sizeof_size(sizeof(struct _ccmode_xts_tweak)) + ccn_sizeof_size(ecb->block_size), \
|
||||
.block_size = ecb->block_size, \
|
||||
.init = ccmode_xts_init, \
|
||||
.set_tweak = ccmode_xts_set_tweak, \
|
||||
.xts = ccmode_xts_crypt, \
|
||||
.custom = (ECB), \
|
||||
.custom1 = (ECB_ENCRYPT) \
|
||||
}
|
||||
|
||||
/* Use this to statically initialize a ccmode_xts object for encryption. */
|
||||
#define CCMODE_FACTORY_XTS_ENCRYPT(ECB, ECB_ENCRYPT) { \
|
||||
.size = ccn_sizeof_size(sizeof(struct _ccmode_xts_key)) + 2 * ccn_sizeof_size((ECB)->size), \
|
||||
.tweak_size = ccn_sizeof_size(sizeof(struct _ccmode_xts_tweak)) + ccn_sizeof_size(ecb->block_size), \
|
||||
.block_size = ecb->block_size, \
|
||||
.init = ccmode_xts_init, \
|
||||
.set_tweak = ccmode_xts_set_tweak, \
|
||||
.xts = ccmode_xts_crypt, \
|
||||
.custom = (ECB), \
|
||||
.custom1 = (ECB_ENCRYPT) \
|
||||
}
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_xts decrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb decrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_xts_decrypt(struct ccmode_xts *xts,
|
||||
const struct ccmode_ecb *ecb,
|
||||
const struct ccmode_ecb *ecb_encrypt);
|
||||
|
||||
/* Use these function to runtime initialize a ccmode_xts encrypt object (for
|
||||
example if it's part of a larger structure). Normally you would pass a
|
||||
ecb encrypt mode implementation of some underlying algorithm as the ecb
|
||||
parameter. */
|
||||
void ccmode_factory_xts_encrypt(struct ccmode_xts *xts,
|
||||
const struct ccmode_ecb *ecb,
|
||||
const struct ccmode_ecb *ecb_encrypt);
|
||||
|
||||
#endif /* _CORECRYPTO_CCMODE_FACTORY_H_ */
|
204
include/corecrypto/ccmode_impl.h
Normal file
204
include/corecrypto/ccmode_impl.h
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* ccmode_impl.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/07/2010
|
||||
*
|
||||
* Copyright (c) 2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCMODE_IMPL_H_
|
||||
#define _CORECRYPTO_CCMODE_IMPL_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
|
||||
/* ECB mode. */
|
||||
cc_aligned_struct(16) ccecb_ctx;
|
||||
|
||||
|
||||
/* Actual symmetric algorithm implementation should provide you one of these. */
|
||||
struct ccmode_ecb {
|
||||
size_t size; /* first argument to ccecb_ctx_decl(). */
|
||||
size_t block_size;
|
||||
void (*init)(const struct ccmode_ecb *ecb, ccecb_ctx *ctx,
|
||||
size_t key_len, const void *key);
|
||||
void (*ecb)(const ccecb_ctx *ctx, size_t nblocks, const void *in,
|
||||
void *out);
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief corecrypto symmetrical encryption and decryption modes
|
||||
*
|
||||
* corecrypto supports 6 stateless en(de)cryption modes and 2 stateful authenticated en(de)cryption modes
|
||||
* stateless modes CBC, CFB, CFB8, CTR, OFB, XTS: They provide 3 interface functions that do not return errors codes
|
||||
* 1- ccmod_xxx_init()
|
||||
* 2- ccmod_xxx_decrypt()
|
||||
* 3- ccmod_xxx_encrypt()
|
||||
*
|
||||
* stateful modes CCM and GCM: They provide 7 interface functions that return error codes if a function is called out of state
|
||||
* 1- ccmod_xxx_init()
|
||||
* 2- ccmod_xxx_setiv()
|
||||
* 3- ccmod_xxx_aad()
|
||||
* 4- ccmod_xxx_decrypt()
|
||||
* 5- ccmod_xxx_encrypt()
|
||||
* 6- ccmod_xxx_finalize()
|
||||
* 7- ccmod_xxx_reset()
|
||||
*
|
||||
* the correct call sequences are:
|
||||
*
|
||||
* calls to 1, 2 and 6 arerequired
|
||||
* 2 and 3 can be called as mant times as needed
|
||||
* calls to 3, 4, 5 can be skipped
|
||||
*
|
||||
* 1, 2*n, 3*n, 4|5, 6
|
||||
* 1, 2*n, , 4|5, 6
|
||||
* 1, 2*n, , , 6
|
||||
* 1, 2*n, 3*n, , 6
|
||||
*/
|
||||
|
||||
// 1- CBC mode, stateless
|
||||
cc_aligned_struct(16) cccbc_ctx;
|
||||
cc_aligned_struct(16) cccbc_iv;
|
||||
|
||||
struct ccmode_cbc {
|
||||
size_t size; /* first argument to cccbc_ctx_decl(). */
|
||||
size_t block_size;
|
||||
void (*init)(const struct ccmode_cbc *cbc, cccbc_ctx *ctx,
|
||||
size_t key_len, const void *key);
|
||||
/* cbc encrypt or decrypt nblocks from in to out, iv will be used and updated. */
|
||||
void (*cbc)(const cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nblocks, const void *in, void *out);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
// 2- CFB mode, stateless
|
||||
cc_aligned_struct(16) cccfb_ctx;
|
||||
|
||||
struct ccmode_cfb {
|
||||
size_t size; /* first argument to cccfb_ctx_decl(). */
|
||||
size_t block_size;
|
||||
void (*init)(const struct ccmode_cfb *cfb, cccfb_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *iv);
|
||||
void (*cfb)(cccfb_ctx *ctx, size_t nbytes, const void *in, void *out);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
// 3- CFB8 mode, stateless
|
||||
cc_aligned_struct(16) cccfb8_ctx;
|
||||
|
||||
struct ccmode_cfb8 {
|
||||
size_t size; /* first argument to cccfb8_ctx_decl(). */
|
||||
size_t block_size;
|
||||
void (*init)(const struct ccmode_cfb8 *cfb8, cccfb8_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *iv);
|
||||
void (*cfb8)(cccfb8_ctx *ctx, size_t nbytes, const void *in, void *out);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
// 4- CTR mode, stateless
|
||||
cc_aligned_struct(16) ccctr_ctx;
|
||||
|
||||
struct ccmode_ctr {
|
||||
size_t size; /* first argument to ccctr_ctx_decl(). */
|
||||
size_t block_size;
|
||||
void (*init)(const struct ccmode_ctr *ctr, ccctr_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *iv);
|
||||
void (*ctr)(ccctr_ctx *ctx, size_t nbytes, const void *in, void *out);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
// 5- OFB mode, stateless
|
||||
cc_aligned_struct(16) ccofb_ctx;
|
||||
|
||||
struct ccmode_ofb {
|
||||
size_t size; /* first argument to ccofb_ctx_decl(). */
|
||||
size_t block_size;
|
||||
void (*init)(const struct ccmode_ofb *ofb, ccofb_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *iv);
|
||||
void (*ofb)(ccofb_ctx *ctx, size_t nbytes, const void *in, void *out);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
// 6- XTS mode, stateless
|
||||
cc_aligned_struct(16) ccxts_ctx;
|
||||
cc_aligned_struct(16) ccxts_tweak;
|
||||
|
||||
struct ccmode_xts {
|
||||
size_t size; /* first argument to ccxts_ctx_decl(). */
|
||||
size_t tweak_size; /* first argument to ccxts_tweak_decl(). */
|
||||
size_t block_size;
|
||||
|
||||
/* Create a xts key from a xts mode object. The tweak_len here
|
||||
determines how long the tweak is in bytes, for each subsequent call to
|
||||
ccmode_xts->xts().
|
||||
key must point to at least 'size' cc_units of free storage.
|
||||
tweak_key must point to at least 'tweak_size' cc_units of free storage. */
|
||||
void (*init)(const struct ccmode_xts *xts, ccxts_ctx *ctx,
|
||||
size_t key_len, const void *key, const void *tweak_key);
|
||||
|
||||
/* Set the tweak (sector number), the block within the sector zero. */
|
||||
void (*set_tweak)(const ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv);
|
||||
|
||||
/* Encrypt blocks for a sector, clients must call set_tweak before calling
|
||||
this function. Return a pointer to the tweak buffer */
|
||||
void *(*xts)(const ccxts_ctx *ctx, ccxts_tweak *tweak,
|
||||
size_t nblocks, const void *in, void *out);
|
||||
|
||||
const void *custom;
|
||||
const void *custom1;
|
||||
};
|
||||
|
||||
//7- GCM mode, statful
|
||||
cc_aligned_struct(16) ccgcm_ctx;
|
||||
#define CCMODE_GCM_DECRYPTOR 78647
|
||||
#define CCMODE_GCM_ENCRYPTOR 4073947
|
||||
|
||||
struct ccmode_gcm {
|
||||
size_t size; /* first argument to ccgcm_ctx_decl(). */
|
||||
int encdec; //is it encrypt or decrypt object
|
||||
size_t block_size;
|
||||
int (*init)(const struct ccmode_gcm *gcm, ccgcm_ctx *ctx,
|
||||
size_t key_len, const void *key);
|
||||
int (*set_iv)(ccgcm_ctx *ctx, size_t iv_size, const void *iv);
|
||||
int (*gmac)(ccgcm_ctx *ctx, size_t nbytes, const void *in); // could just be gcm with NULL out
|
||||
int (*gcm)(ccgcm_ctx *ctx, size_t nbytes, const void *in, void *out);
|
||||
int (*finalize)(ccgcm_ctx *key, size_t tag_size, void *tag);
|
||||
int (*reset)(ccgcm_ctx *ctx);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
//8- GCM mode, statful
|
||||
cc_aligned_struct(16) ccccm_ctx;
|
||||
cc_aligned_struct(16) ccccm_nonce;
|
||||
|
||||
struct ccmode_ccm {
|
||||
size_t size; /* first argument to ccccm_ctx_decl(). */
|
||||
size_t nonce_size; /* first argument to ccccm_nonce_decl(). */
|
||||
size_t block_size;
|
||||
int (*init)(const struct ccmode_ccm *ccm, ccccm_ctx *ctx,
|
||||
size_t key_len, const void *key);
|
||||
int (*set_iv)(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nonce_len, const void *nonce,
|
||||
size_t mac_size, size_t auth_len, size_t data_len);
|
||||
int (*cbcmac)(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in); // could just be ccm with NULL out
|
||||
int (*ccm)(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out);
|
||||
int (*finalize)(ccccm_ctx *key, ccccm_nonce *nonce_ctx, void *mac);
|
||||
int (*reset)(ccccm_ctx *key, ccccm_nonce *nonce_ctx);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
|
||||
/* OMAC mode. */
|
||||
cc_aligned_struct(16) ccomac_ctx;
|
||||
|
||||
struct ccmode_omac {
|
||||
size_t size; /* first argument to ccomac_ctx_decl(). */
|
||||
size_t block_size;
|
||||
void (*init)(const struct ccmode_omac *omac, ccomac_ctx *ctx,
|
||||
size_t tweak_len, size_t key_len, const void *key);
|
||||
int (*omac)(ccomac_ctx *ctx, size_t nblocks,
|
||||
const void *tweak, const void *in, void *out);
|
||||
const void *custom;
|
||||
};
|
||||
|
||||
#endif /* _CORECRYPTO_CCMODE_IMPL_H_ */
|
138
include/corecrypto/ccmode_siv.h
Normal file
138
include/corecrypto/ccmode_siv.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* ccmode_siv.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 11/13/2015
|
||||
*
|
||||
* Copyright (c) 2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCMODE_SIV_H_
|
||||
#define _CORECRYPTO_CCMODE_SIV_H_
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
#include <corecrypto/ccmode.h>
|
||||
#include <corecrypto/ccmode_impl.h>
|
||||
|
||||
#include <corecrypto/cccmac.h>
|
||||
|
||||
/* This provide an implementation of SIV
|
||||
as specified in https://tools.ietf.org/html/rfc5297
|
||||
also in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/siv/siv.pdf
|
||||
Counter Mode where IV is based on CMAC
|
||||
*/
|
||||
|
||||
cc_aligned_struct(16) ccsiv_ctx;
|
||||
|
||||
struct ccmode_siv {
|
||||
size_t size; /* first argument to ccsiv_ctx_decl(). */
|
||||
size_t block_size;
|
||||
int (*init)(const struct ccmode_siv *siv, ccsiv_ctx *ctx,
|
||||
size_t key_len, const uint8_t *key);
|
||||
int (*set_nonce)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out
|
||||
int (*auth)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out
|
||||
int (*crypt)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
|
||||
int (*reset)(ccsiv_ctx *ctx);
|
||||
const struct ccmode_cbc *cbc;
|
||||
const struct ccmode_ctr *ctr;
|
||||
};
|
||||
|
||||
#define ccsiv_ctx_decl(_size_, _name_) cc_ctx_decl(ccsiv_ctx, _size_, _name_)
|
||||
#define ccsiv_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
// Functions
|
||||
|
||||
CC_INLINE size_t ccsiv_context_size(const struct ccmode_siv *mode)
|
||||
{
|
||||
return mode->size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccsiv_block_size(const struct ccmode_siv *mode)
|
||||
{
|
||||
return mode->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccsiv_ciphertext_size(const struct ccmode_siv *mode,
|
||||
size_t plaintext_size)
|
||||
{
|
||||
return plaintext_size+mode->cbc->block_size;
|
||||
}
|
||||
|
||||
CC_INLINE size_t ccsiv_plaintext_size(const struct ccmode_siv *mode,
|
||||
size_t ciphertext_size)
|
||||
{
|
||||
if (ciphertext_size<mode->cbc->block_size) {
|
||||
return 0; // error
|
||||
}
|
||||
return ciphertext_size-mode->cbc->block_size;
|
||||
}
|
||||
|
||||
// In theory, supported key sizes are 32, 48, 64 bytes
|
||||
// In practice, we only support key size 32 bytes due to cmac limitation
|
||||
CC_INLINE int ccsiv_init(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
|
||||
size_t key_byte_len, const uint8_t *key)
|
||||
{
|
||||
return mode->init(mode, ctx, key_byte_len, key);
|
||||
}
|
||||
|
||||
// Process nonce. it is actually just an authenticated data
|
||||
CC_INLINE int ccsiv_set_nonce(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
|
||||
size_t nbytes, const uint8_t *in)
|
||||
{
|
||||
return mode->set_nonce(ctx, nbytes, in);
|
||||
}
|
||||
|
||||
// Process authenticated data. Taken into account for authentication but not
|
||||
// encrypted
|
||||
CC_INLINE int ccsiv_aad(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
|
||||
size_t nbytes, const uint8_t *in)
|
||||
{
|
||||
return mode->auth(ctx, nbytes, in);
|
||||
}
|
||||
|
||||
// Encryption data. Authenticated and encrypted.
|
||||
// Encrypt/Decrypt can only be called once
|
||||
CC_INLINE int ccsiv_crypt(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
|
||||
size_t nbytes, const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
return mode->crypt(ctx, nbytes, in, out);
|
||||
}
|
||||
|
||||
// Clear all context for reuse.
|
||||
// Key is clear to avoid leaking it
|
||||
CC_INLINE int ccsiv_reset(const struct ccmode_siv *mode, ccsiv_ctx *ctx)
|
||||
{
|
||||
return mode->reset(ctx);
|
||||
}
|
||||
|
||||
// One shot with only one vector of adata
|
||||
CC_INLINE int ccsiv_one_shot(const struct ccmode_siv *mode,
|
||||
size_t key_len, const uint8_t *key,
|
||||
unsigned nonce_nbytes, const uint8_t* nonce,
|
||||
unsigned adata_nbytes, const uint8_t* adata,
|
||||
size_t in_nbytes, const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
int rc;
|
||||
ccsiv_ctx_decl(mode->size, ctx);
|
||||
ccsiv_init(mode, ctx, key_len, key);
|
||||
rc=mode->set_nonce(ctx, nonce_nbytes, nonce);
|
||||
if (rc) {return rc;}
|
||||
rc=mode->auth(ctx, adata_nbytes, adata);
|
||||
if (rc) {return rc;}
|
||||
rc=mode->crypt(ctx, in_nbytes, in, out);
|
||||
if (rc) {return rc;}
|
||||
ccsiv_ctx_clear(mode->size, ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ccmode_factory_siv_encrypt(struct ccmode_siv *siv,
|
||||
const struct ccmode_cbc *cbc,
|
||||
const struct ccmode_ctr *ctr);
|
||||
|
||||
void ccmode_factory_siv_decrypt(struct ccmode_siv *siv,
|
||||
const struct ccmode_cbc *cbc,
|
||||
const struct ccmode_ctr *ctr);
|
||||
|
||||
|
||||
#endif /* _CORECRYPTO_CCMODE_H_ */
|
@ -1,27 +1,668 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lubos Dolezel
|
||||
* ccn.h
|
||||
* corecrypto
|
||||
*
|
||||
* This file is part of Darling CoreCrypto.
|
||||
* Created on 11/16/2010
|
||||
*
|
||||
* Darling is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright (c) 2010,2011,2012,2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCN_H
|
||||
#define _CORECRYPTO_CCN_H
|
||||
#include <stdint.h>
|
||||
#ifndef _CORECRYPTO_CCN_H_
|
||||
#define _CORECRYPTO_CCN_H_
|
||||
|
||||
typedef uint64_t cc_unit;
|
||||
#include <corecrypto/cc.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef uint8_t cc_byte;
|
||||
typedef size_t cc_size;
|
||||
|
||||
#if CCN_UNIT_SIZE == 8
|
||||
typedef uint64_t cc_unit; // 64 bit unit
|
||||
typedef int64_t cc_int;
|
||||
#define CCN_LOG2_BITS_PER_UNIT 6 // 2^6 = 64 bits
|
||||
#define CC_UNIT_C(x) UINT64_C(x)
|
||||
#if CCN_UINT128_SUPPORT_FOR_64BIT_ARCH
|
||||
typedef unsigned cc_dunit __attribute__((mode(TI))); // 128 bit double width unit
|
||||
typedef signed cc_dint __attribute__((mode(TI)));
|
||||
#else
|
||||
typedef struct cc_dunit {
|
||||
uint64_t l; //do not change the order of the variables. cc_dunit must be little endian
|
||||
uint64_t h;
|
||||
} cc_dunit;
|
||||
|
||||
typedef struct cc_dint {
|
||||
uint64_t l;
|
||||
uint64_t h;
|
||||
} cc_dint;
|
||||
#endif
|
||||
|
||||
#elif CCN_UNIT_SIZE == 4
|
||||
typedef uint32_t cc_unit; // 32 bit unit
|
||||
typedef uint64_t cc_dunit; // 64 bit double width unit
|
||||
typedef int64_t cc_dint;
|
||||
typedef int32_t cc_int;
|
||||
#define CCN_LOG2_BITS_PER_UNIT 5 // 2^5 = 32 bits
|
||||
#define CC_UNIT_C(x) UINT32_C(x)
|
||||
|
||||
#elif CCN_UNIT_SIZE == 2
|
||||
typedef uint16_t cc_unit; // 16 bit unit
|
||||
typedef uint32_t cc_dunit; // 32 bit double width unit
|
||||
#define CCN_LOG2_BITS_PER_UNIT 4 // 2^4 = 16 bits
|
||||
#define CC_UNIT_C(x) UINT16_C(x)
|
||||
|
||||
#elif CCN_UNIT_SIZE == 1
|
||||
typedef uint8_t cc_unit; // 8 bit unit
|
||||
typedef uint16_t cc_dunit; // 16 bit double width unit
|
||||
#define CCN_LOG2_BITS_PER_UNIT 3 // 2^3 = 8 bits
|
||||
#define CC_UNIT_C(x) UINT8_C(x)
|
||||
|
||||
#else
|
||||
#error invalid CCN_UNIT_SIZE
|
||||
#endif
|
||||
|
||||
// All mp types have units in little endian unit order.
|
||||
typedef cc_unit *ccn_t; // n unit long mp
|
||||
typedef cc_unit *ccnp1_t; // n + 1 unit long mp
|
||||
typedef cc_unit *cc2n_t; // 2 * n unit long mp
|
||||
typedef cc_unit *cc2np2_t; // 2 * n + 2 unit long mp
|
||||
typedef const cc_unit *ccn_in_t; // n unit long mp
|
||||
typedef const cc_unit *ccnp1_in_t; // n + 1 unit long mp
|
||||
typedef const cc_unit *cc2n_in_t; // 2 * n unit long mp
|
||||
typedef const cc_unit *cc2np2_in_t; // 2 * n + 2 unit long mp
|
||||
|
||||
#define CCN_UNIT_BITS (sizeof(cc_unit) * 8)
|
||||
#define CCN_UNIT_MASK ((cc_unit)~0)
|
||||
|
||||
typedef struct {
|
||||
cc_unit *start; // First cc_unit of the workspace
|
||||
cc_unit *end; // address and beyond NOT TO BE TOUCHED
|
||||
} cc_ws,*cc_ws_t;
|
||||
|
||||
/* Conversions between n sizeof and bits */
|
||||
|
||||
/* Returns the sizeof a ccn vector of length _n_ units. */
|
||||
#define ccn_sizeof_n(_n_) (sizeof(cc_unit) * (_n_))
|
||||
|
||||
/* Returns the count (n) of a ccn vector that can represent _bits_. */
|
||||
#define ccn_nof(_bits_) (((_bits_) + CCN_UNIT_BITS - 1) >> CCN_LOG2_BITS_PER_UNIT)
|
||||
|
||||
/* Returns the sizeof a ccn vector that can represent _bits_. */
|
||||
#define ccn_sizeof(_bits_) (ccn_sizeof_n(ccn_nof(_bits_)))
|
||||
|
||||
/* Returns the count (n) of a ccn vector that can represent _size_ bytes. */
|
||||
#define ccn_nof_size(_size_) (((_size_) + CCN_UNIT_SIZE - 1) / CCN_UNIT_SIZE)
|
||||
|
||||
/* Return the max number of bits a ccn vector of _n_ units can hold. */
|
||||
#define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS)
|
||||
|
||||
/* Return the max number of bits a ccn vector of _size_ bytes can hold. */
|
||||
#define ccn_bitsof_size(_size_) ((_size_) * 8)
|
||||
|
||||
/* Return the size of a ccn of size bytes in bytes. */
|
||||
#define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_))
|
||||
|
||||
/* Returns the value of bit _k_ of _ccn_, both are only evaluated once. */
|
||||
#define ccn_bit(_ccn_, _k_) ({__typeof__ (_k_) __k = (_k_); \
|
||||
1 & ((_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] >> (__k & (CCN_UNIT_BITS - 1)));})
|
||||
|
||||
/* Set the value of bit _k_ of _ccn_ to the value _v_ */
|
||||
#define ccn_set_bit(_ccn_, _k_, _v_) ({__typeof__ (_k_) __k = (_k_); \
|
||||
if (_v_) \
|
||||
(_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] |= CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1)); \
|
||||
else \
|
||||
(_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] &= ~(CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1))); \
|
||||
})
|
||||
|
||||
/* Macros for making ccn constants. You must use list of CCN64_C() instances
|
||||
separated by commas, with an optional smaller sized CCN32_C, CCN16_C, or
|
||||
CCN8_C() instance at the end of the list, when making macros to declare
|
||||
larger sized constants. */
|
||||
#define CCN8_C(a0) CC_UNIT_C(0x##a0)
|
||||
|
||||
#if CCN_UNIT_SIZE >= 2
|
||||
#define CCN16_C(a1,a0) CC_UNIT_C(0x##a1##a0)
|
||||
#define ccn16_v(a0) (a0)
|
||||
#elif CCN_UNIT_SIZE == 1
|
||||
#define CCN16_C(a1,a0) CCN8_C(a0),CCN8_C(a1)
|
||||
#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
|
||||
#endif
|
||||
|
||||
#if CCN_UNIT_SIZE >= 4
|
||||
#define CCN32_C(a3,a2,a1,a0) CC_UNIT_C(0x##a3##a2##a1##a0)
|
||||
#define ccn32_v(a0) (a0)
|
||||
#else
|
||||
#define CCN32_C(a3,a2,a1,a0) CCN16_C(a1,a0),CCN16_C(a3,a2)
|
||||
#define ccn32_v(a0) ccn16_v(a0 & UINT16_C(0xffff)),ccn16_v(a0 >> 16)
|
||||
#endif
|
||||
|
||||
#if CCN_UNIT_SIZE == 8
|
||||
#define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CC_UNIT_C(0x##a7##a6##a5##a4##a3##a2##a1##a0)
|
||||
#define CCN40_C(a4,a3,a2,a1,a0) CC_UNIT_C(0x##a4##a3##a2##a1##a0)
|
||||
#define ccn64_v(a0) (a0)
|
||||
//#define ccn64_32(a1,a0) ((a1 << 32) | a0)
|
||||
//#define ccn_uint64(a,i) (a[i])
|
||||
#else
|
||||
#define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN32_C(a7,a6,a5,a4)
|
||||
#define CCN40_C(a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN8_C(a4)
|
||||
#define ccn64_v(a0) ccn32_v((uint64_t)a0 & UINT32_C(0xffffffff)),ccn32_v((uint64_t)a0 >> 32)
|
||||
//#define ccn64_32(a1,a0) ccn32_v(a0),ccn32_v(a1)
|
||||
//#define ccn_uint64(a,i) ((uint64_t)ccn_uint32(a, i << 1 + 1) << 32 | (uint64_t)ccn_uint32(a, i << 1))
|
||||
#endif
|
||||
|
||||
/* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
|
||||
64 bit units respectively. */
|
||||
#if CCN_UNIT_SIZE == 8
|
||||
/* #define ccn_uint16(a,i) ((i & 3) == 3 ? ((uint16_t)(a[i >> 2] >> 48)) : \
|
||||
(i & 3) == 2 ? ((uint16_t)(a[i >> 2] >> 32) & UINT16_C(0xffff)) : \
|
||||
(i & 3) == 1 ? ((uint16_t)(a[i >> 2] >> 16) & UINT16_C(0xffff)) : \
|
||||
((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
|
||||
*/
|
||||
//#define ccn_uint32(a,i) (i & 1 ? ((uint32_t)(a[i >> 1] >> 32)) : ((uint32_t)(a[i >> 1] & UINT32_C(0xffffffff))))
|
||||
#elif CCN_UNIT_SIZE == 4
|
||||
//#define ccn16_v(a0) (a0)
|
||||
//#define ccn32_v(a0) (a0)
|
||||
//#define ccn_uint16(a,i) (i & 1 ? ((uint16_t)(a[i >> 1] >> 16)) : ((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
|
||||
//#define ccn_uint32(a,i) (a[i])
|
||||
#elif CCN_UNIT_SIZE == 2
|
||||
//#define ccn16_v(a0) (a0)
|
||||
//#define ccn32_v(a0,a1) (a1,a0)
|
||||
//#define ccn_uint16(a,i) (a[i])
|
||||
//#define ccn_uint32(a,i) (((uint32_t)a[i << 1 + 1]) << 16 | (uint32_t)a[i << 1]))
|
||||
#elif CCN_UNIT_SIZE == 1
|
||||
//#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
|
||||
//#define ccn_uint16(a,i) ((uint16_t)((a[i << 1 + 1] << 8) | a[i << 1]))
|
||||
//#define ccn_uint32(a,i) ((uint32_t)ccn_uint16(a, i << 1 + 1) << 16 | (uint32_t)ccn_uint16(a, i << 1))
|
||||
#endif
|
||||
|
||||
/* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
|
||||
64 bit units respectively. */
|
||||
#if CCN_UNIT_SIZE == 8
|
||||
|
||||
#define ccn64_32(a1,a0) (((const cc_unit)a1) << 32 | ((const cc_unit)a0))
|
||||
#define ccn32_32(a0) a0
|
||||
#if __LITTLE_ENDIAN__
|
||||
#define ccn32_32_parse(p,i) (((const uint32_t *)p)[i])
|
||||
#else
|
||||
#define ccn32_32_parse(p,i) (((const uint32_t *)p)[i^1])
|
||||
#endif
|
||||
#define ccn32_32_null 0
|
||||
|
||||
#define ccn64_64(a0) a0
|
||||
#define ccn64_64_parse(p,i) p[i]
|
||||
#define ccn64_64_null 0
|
||||
|
||||
#elif CCN_UNIT_SIZE == 4
|
||||
|
||||
#define ccn32_32(a0) a0
|
||||
#define ccn32_32_parse(p,i) p[i]
|
||||
#define ccn32_32_null 0
|
||||
#define ccn64_32(a1,a0) ccn32_32(a0),ccn32_32(a1)
|
||||
|
||||
#define ccn64_64(a1,a0) a0,a1
|
||||
#define ccn64_64_parse(p,i) p[1+(i<<1)],p[i<<1]
|
||||
#define ccn64_64_null 0,0
|
||||
|
||||
#elif CCN_UNIT_SIZE == 2
|
||||
|
||||
#define ccn32_32(a1,a0) a0,a1
|
||||
#define ccn32_32_parse(p,i) p[1+(i<<1)],p[i<<1]
|
||||
#define ccn32_32_null 0,0
|
||||
#define ccn64_32(a3,a2,a1,a0) ccn32_32(a1,a0),ccn32_32(a3,a2)
|
||||
|
||||
#define ccn64_64(a3,a2,a1,a0) a0,a1,a2,a3
|
||||
#define ccn64_64_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
|
||||
#define ccn64_64_null 0,0,0,0
|
||||
|
||||
#elif CCN_UNIT_SIZE == 1
|
||||
|
||||
#define ccn32_32(a3,a2,a1,a0) a0,a1,a2,a3
|
||||
#define ccn32_32_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
|
||||
#define ccn32_32_null 0,0,0,0
|
||||
#define ccn64_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn32_32(a3,a2,a1,a0),ccn32_32(a7,a6,a5,a4)
|
||||
|
||||
#define ccn64_64(a7,a6,a5,a4,a3,a2,a1,a0) a0,a1,a2,a3,a4,a5,a6,a7
|
||||
#define ccn64_64_parse(p,i) p[7+(i<<3)],p[6+(i<<3)],p[5+(i<<3)],p[4+(i<<3)],p[3+(i<<3)],p[2+(i<<3)],p[1+(i<<3)],p[i<<3]
|
||||
#define ccn64_64_null 0,0,0,0,0,0,0,0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */
|
||||
#define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2)
|
||||
#define ccn224_32(a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn32_32(a6)
|
||||
#define ccn256_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6)
|
||||
#define ccn384_32(a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6),ccn64_32(a9,a8),ccn64_32(a11,a10)
|
||||
|
||||
|
||||
#define CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN64_C(b7,b6,b5,b4,b3,b2,b1,b0),\
|
||||
CCN64_C(c7,c6,c5,c4,c3,c2,c1,c0)
|
||||
|
||||
#define CCN200_C(d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN8_C(d0)
|
||||
|
||||
#define CCN224_C(d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN32_C(d3,d2,d1,d0)
|
||||
|
||||
#define CCN232_C(d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN40_C(d4,d3,d2,d1,d0)
|
||||
|
||||
#define CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0)
|
||||
|
||||
#define CCN264_C(e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN8_C(e0)
|
||||
|
||||
#define CCN384_C(f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\
|
||||
CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0)
|
||||
|
||||
#define CCN392_C(g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN384_C(f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN8_C(g0)
|
||||
|
||||
#define CCN528_C(i1,i0,h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
|
||||
CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
|
||||
CCN256_C(h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0),\
|
||||
CCN16_C(i1,i0)
|
||||
|
||||
#define CCN192_N ccn_nof(192)
|
||||
#define CCN224_N ccn_nof(224)
|
||||
#define CCN256_N ccn_nof(256)
|
||||
#define CCN384_N ccn_nof(384)
|
||||
#define CCN512_N ccn_nof(512)
|
||||
#define CCN521_N ccn_nof(521)
|
||||
|
||||
/* Return the number of used units after stripping leading 0 units. */
|
||||
CC_PURE CC_NONNULL2
|
||||
cc_size ccn_n(cc_size n, const cc_unit *s);
|
||||
|
||||
/* s >> k -> r return bits shifted out of least significant word in bits [0, n>
|
||||
{ N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
|
||||
the _multi version doesn't return the shifted bits, but does support multiple
|
||||
word shifts. */
|
||||
CC_NONNULL((2, 3))
|
||||
cc_unit ccn_shift_right(cc_size n, cc_unit *r, const cc_unit *s, size_t k);
|
||||
CC_NONNULL((2, 3))
|
||||
void ccn_shift_right_multi(cc_size n, cc_unit *r,const cc_unit *s, size_t k);
|
||||
|
||||
/* s << k -> r return bits shifted out of most significant word in bits [0, n>
|
||||
{ N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
|
||||
the _multi version doesn't return the shifted bits, but does support multiple
|
||||
word shifts */
|
||||
CC_NONNULL((2, 3))
|
||||
cc_unit ccn_shift_left(cc_size n, cc_unit *r, const cc_unit *s, size_t k);
|
||||
CC_NONNULL((2, 3))
|
||||
void ccn_shift_left_multi(cc_size n, cc_unit *r, const cc_unit *s, size_t k);
|
||||
|
||||
/* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most
|
||||
significant bit that is 1.
|
||||
{ N bit } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL2
|
||||
size_t ccn_bitlen(cc_size n, const cc_unit *s);
|
||||
|
||||
/* Returns the number of bits which are zero before the first one bit
|
||||
counting from least to most significant bit. */
|
||||
CC_NONNULL2
|
||||
size_t ccn_trailing_zeros(cc_size n, const cc_unit *s);
|
||||
|
||||
/* s == 0 -> return true | s != 0 -> return false
|
||||
{ N bit } N = n * sizeof(cc_unit) * 8 */
|
||||
#define ccn_is_zero(_n_, _s_) (!ccn_n(_n_, _s_))
|
||||
|
||||
/* s == 1 -> return true | s != 1 -> return false
|
||||
{ N bit } N = n * sizeof(cc_unit) * 8 */
|
||||
#define ccn_is_one(_n_, _s_) (ccn_n(_n_, _s_) == 1 && _s_[0] == 1)
|
||||
|
||||
#define ccn_is_zero_or_one(_n_, _s_) (((_n_)==0) || ((ccn_n(_n_, _s_) <= 1) && (_s_[0] <= 1)))
|
||||
|
||||
/* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
|
||||
{ N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_PURE CC_NONNULL((2, 3))
|
||||
int ccn_cmp(cc_size n, const cc_unit *s, const cc_unit *t);
|
||||
|
||||
/* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
|
||||
{ N bit, M bit -> int } N = ns * sizeof(cc_unit) * 8 M = nt * sizeof(cc_unit) * 8 */
|
||||
CC_INLINE CC_NONNULL((2, 4))
|
||||
int ccn_cmpn(cc_size ns, const cc_unit *s,
|
||||
cc_size nt, const cc_unit *t) {
|
||||
if (ns > nt) {
|
||||
return 1;
|
||||
} else if (ns < nt) {
|
||||
return -1;
|
||||
}
|
||||
return ccn_cmp(ns, s, t);
|
||||
}
|
||||
|
||||
/* s - t -> r return 1 iff t > s
|
||||
{ N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL((2, 3, 4))
|
||||
cc_unit ccn_sub(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
|
||||
|
||||
/* |s - t| -> r return 1 iff t > s, 0 otherwise */
|
||||
cc_unit ccn_abs(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
|
||||
|
||||
/* s - v -> r return 1 iff v > s return 0 otherwise.
|
||||
{ N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL((2, 3))
|
||||
cc_unit ccn_sub1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v);
|
||||
|
||||
/* s - t -> r return 1 iff t > s
|
||||
{ N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
|
||||
CC_INLINE
|
||||
CC_NONNULL((2, 3, 5))
|
||||
cc_unit ccn_subn(cc_size n, cc_unit *r, const cc_unit *s,
|
||||
cc_size nt, const cc_unit *t) {
|
||||
assert(n >= nt);
|
||||
return ccn_sub1(n - nt, r + nt, s + nt, ccn_sub(nt, r, s, t));
|
||||
}
|
||||
|
||||
|
||||
/* s + t -> r return carry if result doesn't fit in n bits.
|
||||
{ N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL((2, 3, 4))
|
||||
cc_unit ccn_add(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
|
||||
|
||||
/* s + v -> r return carry if result doesn't fit in n bits.
|
||||
{ N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL((2, 3))
|
||||
cc_unit ccn_add1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v);
|
||||
|
||||
/* s + t -> r return carry if result doesn't fit in n bits
|
||||
{ N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
|
||||
CC_INLINE
|
||||
CC_NONNULL((2, 3, 5))
|
||||
cc_unit ccn_addn(cc_size n, cc_unit *r, const cc_unit *s,
|
||||
cc_size nt, const cc_unit *t) {
|
||||
assert(n >= nt);
|
||||
return ccn_add1(n - nt, r + nt, s + nt, ccn_add(nt, r, s, t));
|
||||
}
|
||||
|
||||
|
||||
CC_NONNULL((2, 3, 4))
|
||||
void ccn_lcm(cc_size n, cc_unit *r2n, const cc_unit *s, const cc_unit *t);
|
||||
|
||||
|
||||
/* s * t -> r_2n r_2n must not overlap with s nor t
|
||||
{ n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8
|
||||
{ N bit, N bit -> 2N bit } N = ccn_bitsof(n) */
|
||||
CC_NONNULL((2, 3, 4))
|
||||
void ccn_mul(cc_size n, cc_unit *r_2n, const cc_unit *s, const cc_unit *t);
|
||||
|
||||
/* s * t -> r_2n r_2n must not overlap with s nor t
|
||||
{ n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8
|
||||
{ N bit, N bit -> 2N bit } N = ccn_bitsof(n)
|
||||
Provide a workspace for potential speedup */
|
||||
CC_NONNULL((2, 3, 4, 5))
|
||||
void ccn_mul_ws(cc_size count, cc_unit *r, const cc_unit *s, const cc_unit *t, cc_ws_t ws);
|
||||
|
||||
/* s[0..n) * v -> r[0..n)+return value
|
||||
{ N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL((2, 3))
|
||||
cc_unit ccn_mul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v);
|
||||
|
||||
/* s[0..n) * v + r[0..n) -> r[0..n)+return value
|
||||
{ N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL((2, 3))
|
||||
cc_unit ccn_addmul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v);
|
||||
|
||||
#if 0
|
||||
/* a % d -> n
|
||||
{2 * n bit, n bit -> n bit } n = count * sizeof(cc_unit) * 8 */
|
||||
CC_NONNULL((2, 3, 4))
|
||||
void ccn_mod(cc_size n, cc_unit *r, const cc_unit *a_2n, const cc_unit *d);
|
||||
#endif
|
||||
|
||||
/* r = gcd(s, t).
|
||||
N bit, N bit -> N bit */
|
||||
CC_NONNULL((2, 3, 4))
|
||||
void ccn_gcd(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
|
||||
|
||||
/* r = gcd(s, t).
|
||||
N bit, N bit -> O bit */
|
||||
CC_NONNULL((2, 4, 6))
|
||||
void ccn_gcdn(cc_size rn, cc_unit *r, cc_size sn, const cc_unit *s, cc_size tn, const cc_unit *t);
|
||||
|
||||
/* r = (data, len) treated as a big endian byte array, return -1 if data
|
||||
doesn't fit in r, return 0 otherwise. */
|
||||
CC_NONNULL((2, 4))
|
||||
int ccn_read_uint(cc_size n, cc_unit *r, size_t data_size, const uint8_t *data);
|
||||
|
||||
/* r = (data, len) treated as a big endian byte array, return -1 if data
|
||||
doesn't fit in r, return 0 otherwise.
|
||||
ccn_read_uint strips leading zeroes and doesn't care about sign. */
|
||||
#define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data)
|
||||
|
||||
/* Return actual size in bytes needed to serialize s. */
|
||||
CC_PURE CC_NONNULL2
|
||||
size_t ccn_write_uint_size(cc_size n, const cc_unit *s);
|
||||
|
||||
/* Serialize s, to out.
|
||||
First byte of byte stream is the m.s. byte of s,
|
||||
regardless of the size of cc_unit.
|
||||
|
||||
No assumption is made about the alignment of out.
|
||||
|
||||
The out_size argument should be the value returned from ccn_write_uint_size,
|
||||
and is also the exact number of bytes this function will write to out.
|
||||
If out_size if less than the value returned by ccn_write_uint_size, only the
|
||||
first out_size non-zero most significant octets of s will be written. */
|
||||
CC_NONNULL((2, 4))
|
||||
void ccn_write_uint(cc_size n, const cc_unit *s, size_t out_size, void *out);
|
||||
|
||||
|
||||
CC_INLINE CC_NONNULL((2, 4))
|
||||
cc_size ccn_write_uint_padded(cc_size n, const cc_unit* s, size_t out_size, uint8_t* to)
|
||||
{
|
||||
size_t bytesInKey = ccn_write_uint_size(n, s);
|
||||
cc_size offset = (out_size > bytesInKey) ? out_size - bytesInKey : 0;
|
||||
|
||||
cc_zero(offset, to);
|
||||
ccn_write_uint(n, s, out_size - offset, to + offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/* Return actual size in bytes needed to serialize s as int
|
||||
(adding leading zero if high bit is set). */
|
||||
CC_PURE CC_NONNULL2
|
||||
size_t ccn_write_int_size(cc_size n, const cc_unit *s);
|
||||
|
||||
/* Serialize s, to out.
|
||||
First byte of byte stream is the m.s. byte of s,
|
||||
regardless of the size of cc_unit.
|
||||
|
||||
No assumption is made about the alignment of out.
|
||||
|
||||
The out_size argument should be the value returned from ccn_write_int_size,
|
||||
and is also the exact number of bytes this function will write to out.
|
||||
If out_size if less than the value returned by ccn_write_int_size, only the
|
||||
first out_size non-zero most significant octets of s will be written. */
|
||||
CC_NONNULL((2, 4))
|
||||
void ccn_write_int(cc_size n, const cc_unit *s, size_t out_size, void *out);
|
||||
|
||||
#if CCN_DEDICATED_SQR
|
||||
|
||||
/* s^2 -> r
|
||||
{ n bit -> 2 * n bit } */
|
||||
CC_NONNULL((2, 3))
|
||||
void ccn_sqr(cc_size n, cc_unit *r, const cc_unit *s);
|
||||
|
||||
/* s^2 -> r
|
||||
{ n bit -> 2 * n bit } */
|
||||
CC_NONNULL((2, 3, 4))
|
||||
void ccn_sqr_ws(cc_size n, cc_unit *r, const cc_unit *s, cc_ws_t ws);
|
||||
|
||||
#else
|
||||
|
||||
/* s^2 -> r
|
||||
{ n bit -> 2 * n bit } */
|
||||
CC_INLINE CC_NONNULL((2, 3))
|
||||
void ccn_sqr(cc_size n, cc_unit *r, const cc_unit *s) {
|
||||
ccn_mul(n, r, s, s);
|
||||
}
|
||||
|
||||
/* s^2 -> r
|
||||
{ n bit -> 2 * n bit } */
|
||||
CC_INLINE CC_NONNULL((2, 3, 4))
|
||||
void ccn_sqr_ws(cc_size n, cc_unit *r, const cc_unit *s, cc_ws_t ws) {
|
||||
ccn_mul_ws(n, r, s, s, ws);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* s -> r
|
||||
{ n bit -> n bit } */
|
||||
CC_NONNULL((2, 3))
|
||||
void ccn_set(cc_size n, cc_unit *r, const cc_unit *s);
|
||||
|
||||
CC_INLINE CC_NONNULL2
|
||||
void ccn_zero(cc_size n, cc_unit *r) {
|
||||
cc_zero(ccn_sizeof_n(n),r);
|
||||
}
|
||||
|
||||
CC_INLINE CC_NONNULL2
|
||||
void ccn_clear(cc_size n, cc_unit *r) {
|
||||
cc_clear(ccn_sizeof_n(n),r);
|
||||
}
|
||||
|
||||
CC_NONNULL2
|
||||
void ccn_zero_multi(cc_size n, cc_unit *r, ...);
|
||||
|
||||
CC_INLINE CC_NONNULL2
|
||||
void ccn_seti(cc_size n, cc_unit *r, cc_unit v) {
|
||||
/* assert(n > 0); */
|
||||
r[0] = v;
|
||||
ccn_zero(n - 1, r + 1);
|
||||
}
|
||||
|
||||
CC_INLINE CC_NONNULL((2, 4))
|
||||
void ccn_setn(cc_size n, cc_unit *r, const cc_size s_size, const cc_unit *s) {
|
||||
/* FIXME: assert not available in kernel.
|
||||
assert(n > 0);
|
||||
assert(s_size > 0);
|
||||
assert(s_size <= n);
|
||||
*/
|
||||
ccn_set(s_size, r, s);
|
||||
ccn_zero(n - s_size, r + s_size);
|
||||
}
|
||||
|
||||
#define CC_SWAP_HOST_BIG_64(x) \
|
||||
((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
|
||||
(((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
|
||||
(((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
|
||||
(((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
|
||||
(((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
|
||||
(((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
|
||||
(((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
|
||||
(((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
|
||||
#define CC_SWAP_HOST_BIG_32(x) \
|
||||
((((x) & 0xff000000) >> 24) | \
|
||||
(((x) & 0x00ff0000) >> 8) | \
|
||||
(((x) & 0x0000ff00) << 8) | \
|
||||
(((x) & 0x000000ff) << 24))
|
||||
#define CC_SWAP_HOST_BIG_16(x) \
|
||||
((((x) & 0xff00) >> 8) | \
|
||||
(((x) & 0x00ff) << 8))
|
||||
|
||||
/* This should probably move if we move ccn_swap out of line. */
|
||||
#if CCN_UNIT_SIZE == 8
|
||||
#define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_64(x)
|
||||
#elif CCN_UNIT_SIZE == 4
|
||||
#define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_32(x)
|
||||
#elif CCN_UNIT_SIZE == 2
|
||||
#define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_16(x)
|
||||
#elif CCN_UNIT_SIZE == 1
|
||||
#define CC_UNIT_TO_BIG(x) (x)
|
||||
#else
|
||||
#error unsupported CCN_UNIT_SIZE
|
||||
#endif
|
||||
|
||||
/* Swap units in r in place from cc_unit vector byte order to big endian byte order (or back). */
|
||||
CC_INLINE CC_NONNULL2
|
||||
void ccn_swap(cc_size n, cc_unit *r) {
|
||||
cc_unit *e;
|
||||
for (e = r + n - 1; r < e; ++r, --e) {
|
||||
cc_unit t = CC_UNIT_TO_BIG(*r);
|
||||
*r = CC_UNIT_TO_BIG(*e);
|
||||
*e = t;
|
||||
}
|
||||
if (n & 1)
|
||||
*r = CC_UNIT_TO_BIG(*r);
|
||||
}
|
||||
|
||||
CC_INLINE CC_NONNULL((2, 3, 4))
|
||||
void ccn_xor(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) {
|
||||
while (n--) {
|
||||
r[n] = s[n] ^ t[n];
|
||||
}
|
||||
}
|
||||
|
||||
/* Debugging */
|
||||
CC_NONNULL2
|
||||
void ccn_print(cc_size n, const cc_unit *s);
|
||||
CC_NONNULL3
|
||||
void ccn_lprint(cc_size n, const char *label, const cc_unit *s);
|
||||
|
||||
/* Forward declaration so we don't depend on ccrng.h. */
|
||||
struct ccrng_state;
|
||||
|
||||
#if 0
|
||||
CC_INLINE CC_NONNULL((2, 3))
|
||||
int ccn_random(cc_size n, cc_unit *r, struct ccrng_state *rng) {
|
||||
return (RNG)->generate((RNG), ccn_sizeof_n(n), (unsigned char *)r);
|
||||
}
|
||||
#else
|
||||
#define ccn_random(_n_,_r_,_ccrng_ctx_) \
|
||||
ccrng_generate(_ccrng_ctx_, ccn_sizeof_n(_n_), (unsigned char *)_r_)
|
||||
#endif
|
||||
|
||||
/* Make a ccn of size ccn_nof(nbits) units with up to nbits sized random value. */
|
||||
CC_NONNULL((2, 3))
|
||||
int ccn_random_bits(cc_size nbits, cc_unit *r, struct ccrng_state *rng);
|
||||
|
||||
/*!
|
||||
@brief ccn_make_recip(cc_size nd, cc_unit *recip, const cc_unit *d) computes the reciprocal of d: recip = 2^2b/d where b=bitlen(d)
|
||||
|
||||
@param nd length of array d
|
||||
@param recip returned reciprocal of size nd+1
|
||||
@param d input number d
|
||||
*/
|
||||
CC_NONNULL((2, 3))
|
||||
void ccn_make_recip(cc_size nd, cc_unit *recip, const cc_unit *d);
|
||||
|
||||
CC_NONNULL((6, 8))
|
||||
int ccn_div_euclid(cc_size nq, cc_unit *q, cc_size nr, cc_unit *r, cc_size na, const cc_unit *a, cc_size nd, const cc_unit *d);
|
||||
|
||||
#define ccn_div(nq, q, na, a, nd, d) ccn_div_euclid(nq, q, 0, NULL, na, a, nd, d)
|
||||
#define ccn_mod(nr, r, na, a, nd, d) ccn_div_euclid(0 , NULL, nr, r, na, a, nd, d)
|
||||
|
||||
/*!
|
||||
@brief ccn_div_use_recip(nq, q, nr, r, na, a, nd, d) comutes q=a/d and r=a%d
|
||||
@discussion q and rcan be NULL. Reads na from a and nd from d. Writes nq in q and nr in r. nq and nr must be large enough to accomodate results, otherwise error is retuned. Execution time depends on the size of a. Computation is perfomed on of fixedsize and the leadig zeros of a of q are are also used in the computation.
|
||||
@param nq length of array q that hold the quotients. The maximum length of quotient is the actual length of dividend a
|
||||
@param q returned quotient. If nq is larger than needed, it is filled with leading zeros. If it is smaller, error is returned. q can be set to NULL, if not needed.
|
||||
@param nr length of array r that hold the remainder. The maximum length of remainder is the actual length of divisor d
|
||||
@param r returned remainder. If nr is larger than needed, it is filled with leading zeros. Ifi is smaller error is returned. r can be set to NULL if not required.
|
||||
@param na length of dividend. Dividend may have leading zeros.
|
||||
@param a input Dividend
|
||||
@param nd length of input divisor. Divisor may have leading zeros.
|
||||
@param d input Divisor
|
||||
@param recip_d The reciprocal of d, of length nd+1.
|
||||
|
||||
@return returns 0 if successful, negative of error.
|
||||
*/
|
||||
CC_NONNULL((6, 8, 9))
|
||||
int ccn_div_use_recip(cc_size nq, cc_unit *q, cc_size nr, cc_unit *r, cc_size na, const cc_unit *a, cc_size nd, const cc_unit *d, const cc_unit *recip_d);
|
||||
|
||||
#endif /* _CORECRYPTO_CCN_H_ */
|
||||
|
73
include/corecrypto/ccpad.h
Normal file
73
include/corecrypto/ccpad.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* ccpad.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/07/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCPAD_H_
|
||||
#define _CORECRYPTO_CCPAD_H_
|
||||
|
||||
#include <corecrypto/ccmode.h>
|
||||
|
||||
// CTS1,2,3 are defined in Addendum to 800-38A,
|
||||
// "Cipher Modes of Operation: Three Variants of Ciphertext Stealing for CBC Mode"
|
||||
// CTS3 is also known as "CTS" in RFC3962
|
||||
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
size_t ccpad_cts1_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
size_t ccpad_cts1_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
size_t ccpad_cts2_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
size_t ccpad_cts2_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
size_t ccpad_cts3_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
size_t ccpad_cts3_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Contract is nbytes is non zero and a multiple of block_size. Furthermore in is nbytes long and out is nbytes long. Returns number of bytes written to out (technically we always write nbytes to out but the returned value is the number of bytes decrypted after removal of padding.
|
||||
|
||||
To be safe we remove the entire offending block if the pkcs7 padding checks failed. However we purposely don't report the failure to decode the padding since any use of this error leads to potential security exploits. So currently there is no way to distinguish between a full block of padding and bad padding.
|
||||
*/
|
||||
size_t ccpad_pkcs7_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Contract is in is nbytes long. Writes (nbytes / block_size) + 1 times block_size to out. In other words, out must be nbytes rounded down to the closest multiple of block_size plus block_size bytes. */
|
||||
size_t ccpad_pkcs7_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Contract is 'don't break CommonCrypto functionality that allows PKCS7 padding with ECB mode'. This is basically the same routines above, without an IV, because calling
|
||||
crypt with an IV makes ecb cry (and crash) */
|
||||
|
||||
size_t ccpad_pkcs7_ecb_decrypt(const struct ccmode_ecb *ecb, ccecb_ctx *ecb_key,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
size_t ccpad_pkcs7_ecb_encrypt(const struct ccmode_ecb *ecb, ccecb_ctx *ctx,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Function common to ccpad_pkcs7_ecb_decrypt and ccpad_pkcs7_decrypt */
|
||||
size_t ccpad_pkcs7_decode(const size_t block_size, const uint8_t* last_block);
|
||||
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
size_t ccpad_xts_decrypt(const struct ccmode_xts *xts, ccxts_ctx *ctx, ccxts_tweak *tweak,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
|
||||
void ccpad_xts_encrypt(const struct ccmode_xts *xts, ccxts_ctx *ctx, ccxts_tweak *tweak,
|
||||
size_t nbytes, const void *in, void *out);
|
||||
|
||||
#endif /* _CORECRYPTO_CCPAD_H_ */
|
42
include/corecrypto/ccpbkdf2.h
Normal file
42
include/corecrypto/ccpbkdf2.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* ccpbkdf2.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/15/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCPBKDF2_H_
|
||||
#define _CORECRYPTO_CCPBKDF2_H_
|
||||
|
||||
#include <corecrypto/ccdigest.h>
|
||||
|
||||
/*! @function ccpbkdf2_hmac
|
||||
@abstract perform a pbkdf2 using HMAC(di) for the PRF (see PKCS#5 for specification)
|
||||
@discussion This performs a standard PBKDF2 transformation of password and salt through
|
||||
an HMAC PRF of the callers slection (any Digest, typically SHA-1) returning dkLen bytes
|
||||
containing the entropy.
|
||||
|
||||
Considerations:
|
||||
The salt used should be at least 8 bytes long. Each session should use it's own salt.
|
||||
We use the password as the key for the HMAC and the running data as the text for the HMAC to make a PRF.
|
||||
SHA-1 is a good hash to use for the core of the HMAC PRF.
|
||||
@param di digest info defining the digest type to use in the PRF.
|
||||
@param passwordLen amount of data to be fed in
|
||||
@param password data to be fed into the PBKDF
|
||||
@param saltLen length of the salt
|
||||
@param salt salt to be used in pbkdf
|
||||
@param iterations itrations to go
|
||||
@param dkLen length of the results
|
||||
@param dk buffer for the results of the PBKDF tranformation, must be dkLen big
|
||||
|
||||
*/
|
||||
int ccpbkdf2_hmac(const struct ccdigest_info *di,
|
||||
size_t passwordLen, const void *password,
|
||||
size_t saltLen, const void *salt,
|
||||
size_t iterations,
|
||||
size_t dkLen, void *dk);
|
||||
|
||||
#endif /* _CORECRYPTO_CCPBKDF2_H_ */
|
44
include/corecrypto/ccrc4.h
Normal file
44
include/corecrypto/ccrc4.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* ccrc4.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/22/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2012,2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCRC4_H_
|
||||
#define _CORECRYPTO_CCRC4_H_
|
||||
|
||||
#include <corecrypto/ccmode.h>
|
||||
|
||||
cc_aligned_struct(16) ccrc4_ctx;
|
||||
|
||||
/* Declare a rc4 key named _name_. Pass the size field of a struct ccmode_ecb
|
||||
for _size_. */
|
||||
#define ccrc4_ctx_decl(_size_, _name_) cc_ctx_decl(ccrc4_ctx, _size_, _name_)
|
||||
#define ccrc4_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
|
||||
|
||||
struct ccrc4_info {
|
||||
size_t size; /* first argument to ccrc4_ctx_decl(). */
|
||||
void (*init)(ccrc4_ctx *ctx, size_t key_len, const void *key);
|
||||
void (*crypt)(ccrc4_ctx *ctx, size_t nbytes, const void *in, void *out);
|
||||
};
|
||||
|
||||
|
||||
const struct ccrc4_info *ccrc4(void);
|
||||
|
||||
extern const struct ccrc4_info ccrc4_eay;
|
||||
|
||||
struct ccrc4_vector {
|
||||
size_t keylen;
|
||||
const void *key;
|
||||
size_t datalen;
|
||||
const void *pt;
|
||||
const void *ct;
|
||||
};
|
||||
|
||||
int ccrc4_test(const struct ccrc4_info *rc4, const struct ccrc4_vector *v);
|
||||
|
||||
#endif /* _CORECRYPTO_CCRC4_H_ */
|
43
include/corecrypto/ccrng.h
Normal file
43
include/corecrypto/ccrng.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* ccrng.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/13/2010
|
||||
*
|
||||
* Copyright (c) 2010,2011,2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCRNG_H_
|
||||
#define _CORECRYPTO_CCRNG_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <corecrypto/cc.h>
|
||||
|
||||
#define CC_ERR_DEVICE -100
|
||||
#define CC_ERR_INTERUPTS -101
|
||||
#define CC_ERR_CRYPTO_CONFIG -102
|
||||
#define CC_ERR_PERMS -103
|
||||
#define CC_ERR_PARAMETER -104
|
||||
#define CC_ERR_MEMORY -105
|
||||
#define CC_ERR_FILEDESC -106
|
||||
#define CC_ERR_OUT_OF_ENTROPY -107
|
||||
#define CC_ERR_INTERNAL -108
|
||||
#define CC_ERR_ATFORK -109
|
||||
#define CC_ERR_OVERFLOW -110
|
||||
|
||||
#define CCRNG_STATE_COMMON \
|
||||
int (*generate)(struct ccrng_state *rng, size_t outlen, void *out);
|
||||
|
||||
/* Get a pointer to a ccrng has never been simpler! Just call this */
|
||||
struct ccrng_state *ccrng(int *error);
|
||||
|
||||
/* default state structure - do not instantiate, instead use the specific one you need */
|
||||
struct ccrng_state {
|
||||
CCRNG_STATE_COMMON
|
||||
};
|
||||
|
||||
#define ccrng_generate(ctx, outlen, out) ((ctx)->generate((ctx), (outlen), (out)))
|
||||
|
||||
#endif /* _CORECRYPTO_CCRNG_H_ */
|
42
include/corecrypto/ccrng_system.h
Normal file
42
include/corecrypto/ccrng_system.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* ccrng_system.h
|
||||
* corecrypto
|
||||
*
|
||||
* Created on 12/13/2010
|
||||
*
|
||||
* Copyright (c) 2010,2013,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCRNG_SYSTEM_H_
|
||||
#define _CORECRYPTO_CCRNG_SYSTEM_H_
|
||||
|
||||
#include <corecrypto/ccrng.h>
|
||||
|
||||
struct ccrng_system_state {
|
||||
CCRNG_STATE_COMMON
|
||||
int fd;
|
||||
};
|
||||
|
||||
/*!
|
||||
@function ccrng_system_init - DEPRECATED
|
||||
@abstract Default ccrng.
|
||||
Please transition to ccrng() which is easier to use and with provide the fastest, most secure option
|
||||
|
||||
@param rng Structure containing the state of the RNG, must remain allocated as
|
||||
long as the rng is used.
|
||||
@result 0 iff successful
|
||||
|
||||
@discussion
|
||||
This RNG require call to "init" AND "done", otherwise it may leak a file descriptor.
|
||||
*/
|
||||
|
||||
// Initialize ccrng
|
||||
// Deprecated, if you need a rng, just call the function ccrng()
|
||||
int ccrng_system_init(struct ccrng_system_state *rng);
|
||||
|
||||
// Close the system RNG
|
||||
// Mandatory step to avoid leaking file descriptor
|
||||
void ccrng_system_done(struct ccrng_system_state *rng);
|
||||
|
||||
#endif /* _CORECRYPTO_CCRNG_SYSTEM_H_ */
|
0
include/corecrypto/ccrsa_priv.h
Normal file
0
include/corecrypto/ccrsa_priv.h
Normal file
@ -1,24 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lubos Dolezel
|
||||
* ccsha1.h
|
||||
* corecrypto
|
||||
*
|
||||
* This file is part of Darling CoreCrypto.
|
||||
* Created on 12/01/2010
|
||||
*
|
||||
* Darling is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCSHA1_H
|
||||
#define _CORECRYPTO_CCSHA1_H
|
||||
#ifndef _CORECRYPTO_CCSHA1_H_
|
||||
#define _CORECRYPTO_CCSHA1_H_
|
||||
|
||||
#include <corecrypto/ccdigest.h>
|
||||
#include <corecrypto/cc_config.h>
|
||||
@ -27,15 +18,35 @@
|
||||
#define CCSHA1_OUTPUT_SIZE 20
|
||||
#define CCSHA1_STATE_SIZE 20
|
||||
|
||||
/* sha1 selector */
|
||||
const struct ccdigest_info *ccsha1_di(void);
|
||||
|
||||
extern const uint32_t ccsha1_initial_state[5];
|
||||
|
||||
/* shared between several implementations */
|
||||
void ccsha1_final(const struct ccdigest_info *di, ccdigest_ctx_t,
|
||||
unsigned char *digest);
|
||||
|
||||
|
||||
/* Implementations */
|
||||
extern const struct ccdigest_info ccsha1_ltc_di;
|
||||
extern const struct ccdigest_info ccsha1_eay_di;
|
||||
|
||||
#if CCSHA1_VNG_INTEL
|
||||
//extern const struct ccdigest_info ccsha1_vng_intel_di;
|
||||
#if defined(__x86_64__)
|
||||
extern const struct ccdigest_info ccsha1_vng_intel_AVX2_di;
|
||||
extern const struct ccdigest_info ccsha1_vng_intel_AVX1_di;
|
||||
#endif
|
||||
extern const struct ccdigest_info ccsha1_vng_intel_SupplementalSSE3_di;
|
||||
#endif
|
||||
|
||||
#if CCSHA1_VNG_ARMV7NEON
|
||||
extern const struct ccdigest_info ccsha1_vng_armv7neon_di;
|
||||
#endif
|
||||
|
||||
/* TODO: Placeholders */
|
||||
#define ccoid_sha1 ((unsigned char *)"\x06\x05\x2b\x0e\x03\x02\x1a")
|
||||
#define ccoid_sha1_len 7
|
||||
|
||||
#endif /* _CORECRYPTO_CCSHA1_H_ */
|
||||
|
@ -1,49 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lubos Dolezel
|
||||
* ccsha2.h
|
||||
* corecrypto
|
||||
*
|
||||
* This file is part of Darling CoreCrypto.
|
||||
* Created on 12/03/2010
|
||||
*
|
||||
* Darling is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CORECRYPTO_CCSHA2_H
|
||||
#define _CORECRYPTO_CCSHA2_H
|
||||
#ifndef _CORECRYPTO_CCSHA2_H_
|
||||
#define _CORECRYPTO_CCSHA2_H_
|
||||
|
||||
#include <corecrypto/ccdigest.h>
|
||||
|
||||
/* sha2 selectors */
|
||||
const struct ccdigest_info *ccsha224_di(void);
|
||||
const struct ccdigest_info *ccsha256_di(void);
|
||||
const struct ccdigest_info *ccsha384_di(void);
|
||||
const struct ccdigest_info *ccsha512_di(void);
|
||||
|
||||
/* TODO: Placeholders */
|
||||
#define ccoid_sha224 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04")
|
||||
#define ccoid_sha224_len 11
|
||||
|
||||
#define ccoid_sha256 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01")
|
||||
#define ccoid_sha256_len 11
|
||||
|
||||
#define ccoid_sha384 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02")
|
||||
#define ccoid_sha384_len 11
|
||||
|
||||
#define ccoid_sha512 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03")
|
||||
#define ccoid_sha512_len 11
|
||||
|
||||
|
||||
/* SHA256 */
|
||||
#define CCSHA256_BLOCK_SIZE 64
|
||||
#define CCSHA256_OUTPUT_SIZE 32
|
||||
#define CCSHA256_STATE_SIZE 32
|
||||
|
||||
extern const struct ccdigest_info ccsha256_ltc_di;
|
||||
extern const struct ccdigest_info ccsha256_v6m_di;
|
||||
#if CCSHA2_VNG_INTEL
|
||||
#if defined __x86_64__
|
||||
extern const struct ccdigest_info ccsha224_vng_intel_AVX2_di;
|
||||
extern const struct ccdigest_info ccsha224_vng_intel_AVX1_di;
|
||||
extern const struct ccdigest_info ccsha256_vng_intel_AVX2_di;
|
||||
extern const struct ccdigest_info ccsha256_vng_intel_AVX1_di;
|
||||
extern const struct ccdigest_info ccsha384_vng_intel_AVX2_di;
|
||||
extern const struct ccdigest_info ccsha384_vng_intel_AVX1_di;
|
||||
extern const struct ccdigest_info ccsha384_vng_intel_SupplementalSSE3_di;
|
||||
extern const struct ccdigest_info ccsha512_vng_intel_AVX2_di;
|
||||
extern const struct ccdigest_info ccsha512_vng_intel_AVX1_di;
|
||||
extern const struct ccdigest_info ccsha512_vng_intel_SupplementalSSE3_di;
|
||||
#endif
|
||||
extern const struct ccdigest_info ccsha256_vng_intel_SupplementalSSE3_di;
|
||||
#endif
|
||||
#if CCSHA2_VNG_ARMV7NEON
|
||||
extern const struct ccdigest_info ccsha256_vng_armv7neon_di;
|
||||
extern const struct ccdigest_info ccsha384_vng_arm64_di;
|
||||
extern const struct ccdigest_info ccsha384_vng_armv7neon_di;
|
||||
extern const struct ccdigest_info ccsha512_vng_arm64_di;
|
||||
extern const struct ccdigest_info ccsha512_vng_armv7neon_di;
|
||||
#endif
|
||||
extern const uint32_t ccsha256_K[64];
|
||||
extern const uint64_t ccsha512_K[80];
|
||||
|
||||
/* SHA224 */
|
||||
#define CCSHA224_OUTPUT_SIZE 28
|
||||
extern const struct ccdigest_info ccsha224_ltc_di;
|
||||
#if CCSHA2_VNG_INTEL
|
||||
extern const struct ccdigest_info ccsha224_vng_intel_SupplementalSSE3_di;
|
||||
#endif
|
||||
#if CCSHA2_VNG_ARMV7NEON
|
||||
extern const struct ccdigest_info ccsha224_vng_armv7neon_di;
|
||||
#endif
|
||||
|
||||
/* SHA512 */
|
||||
#define CCSHA512_BLOCK_SIZE 128
|
||||
#define CCSHA512_OUTPUT_SIZE 64
|
||||
#define CCSHA512_STATE_SIZE 64
|
||||
extern const struct ccdigest_info ccsha512_ltc_di;
|
||||
|
||||
/* SHA384 */
|
||||
#define CCSHA384_OUTPUT_SIZE 48
|
||||
extern const struct ccdigest_info ccsha384_ltc_di;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _CORECRYPTO_CCSHA2_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user