mirror of https://github.com/ARMmbed/mbed-os.git
Integrate NUC472 DES/TDES accelerator
parent
aa4e880b4a
commit
7fbd2b607e
|
@ -0,0 +1,42 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015-2016 Nuvoton
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "mbed_assert.h"
|
||||
#include "nu_modutil.h"
|
||||
#include "nu_bitutil.h"
|
||||
|
||||
static int crypto_inited = 0;
|
||||
|
||||
void crypto_init(void)
|
||||
{
|
||||
if (crypto_inited) {
|
||||
return;
|
||||
}
|
||||
crypto_inited = 1;
|
||||
|
||||
CLK_EnableModuleClock(CRPT_MODULE);
|
||||
}
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
void crypto_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = (unsigned char*) v;
|
||||
while (n--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015-2016 Nuvoton
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBED_CRYPTO_H
|
||||
#define MBED_CRYPTO_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void crypto_init(void);
|
||||
void crypto_zeroize(void *v, size_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,410 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015-2016 Nuvoton
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
#if defined(MBEDTLS_DES_ALT)
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/des.h"
|
||||
#include "des_alt.h"
|
||||
#include "crypto.h"
|
||||
#include "nu_bitutil.h"
|
||||
#include "toolchain.h"
|
||||
|
||||
// Must be a multiple of 64-bit block size
|
||||
#define MAXSIZE_DMABUF (8 * 5)
|
||||
static uint8_t dmabuf_in[MAXSIZE_DMABUF] MBED_ALIGN(4);
|
||||
static uint8_t dmabuf_out[MAXSIZE_DMABUF] MBED_ALIGN(4);
|
||||
|
||||
static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length,
|
||||
unsigned char iv[8], const unsigned char *input, unsigned char *output);
|
||||
|
||||
void mbedtls_des_init(mbedtls_des_context *ctx)
|
||||
{
|
||||
crypto_init();
|
||||
memset(ctx, 0, sizeof(mbedtls_des_context));
|
||||
}
|
||||
|
||||
void mbedtls_des_free( mbedtls_des_context *ctx )
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
crypto_zeroize(ctx, sizeof(mbedtls_des_context));
|
||||
}
|
||||
|
||||
void mbedtls_des3_init( mbedtls_des3_context *ctx )
|
||||
{
|
||||
crypto_init();
|
||||
memset(ctx, 0, sizeof(mbedtls_des3_context));
|
||||
}
|
||||
|
||||
void mbedtls_des3_free( mbedtls_des3_context *ctx )
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
crypto_zeroize(ctx, sizeof (mbedtls_des3_context));
|
||||
}
|
||||
|
||||
static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
|
||||
11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
|
||||
47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
|
||||
82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
|
||||
115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
|
||||
143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
|
||||
171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
|
||||
199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
|
||||
227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
|
||||
254 };
|
||||
|
||||
void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) {
|
||||
key[i] = odd_parity_table[key[i] / 2];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the given key's parity, returns 1 on failure, 0 on SUCCESS
|
||||
*/
|
||||
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
|
||||
if( key[i] != odd_parity_table[key[i] / 2] )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Table of weak and semi-weak keys
|
||||
*
|
||||
* Source: http://en.wikipedia.org/wiki/Weak_key
|
||||
*
|
||||
* Weak:
|
||||
* Alternating ones + zeros (0x0101010101010101)
|
||||
* Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
|
||||
* '0xE0E0E0E0F1F1F1F1'
|
||||
* '0x1F1F1F1F0E0E0E0E'
|
||||
*
|
||||
* Semi-weak:
|
||||
* 0x011F011F010E010E and 0x1F011F010E010E01
|
||||
* 0x01E001E001F101F1 and 0xE001E001F101F101
|
||||
* 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
|
||||
* 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
|
||||
* 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
|
||||
* 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
|
||||
*
|
||||
*/
|
||||
|
||||
#define WEAK_KEY_COUNT 16
|
||||
|
||||
static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
|
||||
{
|
||||
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
|
||||
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
|
||||
{ 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
|
||||
|
||||
{ 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
|
||||
{ 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
|
||||
{ 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
|
||||
{ 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
|
||||
{ 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
|
||||
{ 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
|
||||
{ 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
|
||||
{ 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
|
||||
{ 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
|
||||
{ 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
|
||||
{ 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
|
||||
{ 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
|
||||
};
|
||||
|
||||
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < WEAK_KEY_COUNT; i++ )
|
||||
if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* DES key schedule (56-bit, encryption)
|
||||
*/
|
||||
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
|
||||
{
|
||||
ctx->enc = 1;
|
||||
// Keying option 3: All three keys are identical, i.e. K1 = K2 = K3.
|
||||
ctx->keyopt = 3;
|
||||
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[1], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DES key schedule (56-bit, decryption)
|
||||
*/
|
||||
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
|
||||
{
|
||||
ctx->enc = 0;
|
||||
// Keying option 3: All three keys are identical, i.e. K1 = K2 = K3.
|
||||
ctx->keyopt = 3;
|
||||
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[1], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (112-bit, encryption)
|
||||
*/
|
||||
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
|
||||
{
|
||||
ctx->enc = 1;
|
||||
// Keying option 2: K1 and K2 are independent, and K3 = K1.
|
||||
ctx->keyopt = 2;
|
||||
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (112-bit, decryption)
|
||||
*/
|
||||
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
|
||||
{
|
||||
ctx->enc = 0;
|
||||
// Keying option 2: K1 and K2 are independent, and K3 = K1.
|
||||
ctx->keyopt = 2;
|
||||
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (168-bit, encryption)
|
||||
*/
|
||||
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
|
||||
{
|
||||
ctx->enc = 1;
|
||||
// Keying option 1: All three keys are independent.
|
||||
ctx->keyopt = 1;
|
||||
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[2], key + MBEDTLS_DES_KEY_SIZE * 2, MBEDTLS_DES_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Triple-DES key schedule (168-bit, decryption)
|
||||
*/
|
||||
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
|
||||
{
|
||||
ctx->enc = 0;
|
||||
// Keying option 1: All three keys are independent.
|
||||
ctx->keyopt = 1;
|
||||
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
|
||||
memcpy(ctx->key[2], key + MBEDTLS_DES_KEY_SIZE * 2, MBEDTLS_DES_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DES-ECB block encryption/decryption
|
||||
*/
|
||||
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] )
|
||||
{
|
||||
unsigned char iv[8] = {0x00};
|
||||
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, ctx->enc, DES_MODE_ECB, 8, iv, input, output);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/*
|
||||
* DES-CBC buffer encryption/decryption
|
||||
*/
|
||||
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, mode == MBEDTLS_DES_ENCRYPT, DES_MODE_CBC, length, iv, input, output);
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
/*
|
||||
* 3DES-ECB block encryption/decryption
|
||||
*/
|
||||
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] )
|
||||
{
|
||||
unsigned char iv[8] = {0x00};
|
||||
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, ctx->enc, TDES_MODE_ECB, 8, iv, input, output);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/*
|
||||
* 3DES-CBC buffer encryption/decryption
|
||||
*/
|
||||
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, mode == MBEDTLS_DES_ENCRYPT, TDES_MODE_CBC, length, iv, input, output);
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
|
||||
|
||||
static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length,
|
||||
unsigned char iv[8], const unsigned char *input, unsigned char *output)
|
||||
{
|
||||
if (length % 8) {
|
||||
return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
|
||||
}
|
||||
|
||||
// NOTE: Don't call driver function TDES_Open in BSP because it doesn't support TDES_CTL[3KEYS] setting.
|
||||
CRPT->TDES_CTL = (0 << CRPT_TDES_CTL_CHANNEL_Pos) | (enc << CRPT_TDES_CTL_ENCRPT_Pos) |
|
||||
tdes_opmode | (TDES_IN_OUT_WHL_SWAP << CRPT_TDES_CTL_BLKSWAP_Pos);
|
||||
|
||||
// Keying option 1: All three keys are independent.
|
||||
// Keying option 2: K1 and K2 are independent, and K3 = K1.
|
||||
// Keying option 3: All three keys are identical, i.e. K1 = K2 = K3.
|
||||
if (keyopt == 1) {
|
||||
CRPT->TDES_CTL |= CRPT_TDES_CTL_3KEYS_Msk;
|
||||
}
|
||||
else {
|
||||
CRPT->TDES_CTL &= ~CRPT_TDES_CTL_3KEYS_Msk;
|
||||
}
|
||||
|
||||
// Set DES/TDES keys
|
||||
// NOTE: Don't call driver function TDES_SetKey in BSP because it doesn't support endian swap.
|
||||
uint32_t val;
|
||||
volatile uint32_t *tdes_key = (uint32_t *) ((uint32_t) &CRPT->TDES0_KEY1H + (0x40 * 0));
|
||||
val = nu_get32_be(key[0] + 0);
|
||||
*tdes_key ++ = val;
|
||||
val = nu_get32_be(key[0] + 4);
|
||||
*tdes_key ++ = val;
|
||||
val = nu_get32_be(key[1] + 0);
|
||||
*tdes_key ++ = val;
|
||||
val = nu_get32_be(key[1] + 4);
|
||||
*tdes_key ++ = val;
|
||||
val = nu_get32_be(key[2] + 0);
|
||||
*tdes_key ++ = val;
|
||||
val = nu_get32_be(key[2] + 4);
|
||||
*tdes_key ++ = val;
|
||||
|
||||
uint32_t rmn = length;
|
||||
const unsigned char *in_pos = input;
|
||||
const unsigned char *out_pos = output;
|
||||
|
||||
while (rmn) {
|
||||
uint32_t data_len = (rmn <= MAXSIZE_DMABUF) ? rmn : MAXSIZE_DMABUF;
|
||||
|
||||
uint32_t ivh, ivl;
|
||||
ivh = nu_get32_be(iv);
|
||||
ivl = nu_get32_be(iv + 4);
|
||||
TDES_SetInitVect(0, ivh, ivl);
|
||||
|
||||
memcpy(dmabuf_in, in_pos, data_len);
|
||||
|
||||
TDES_SetDMATransfer(0, (uint32_t) dmabuf_in, (uint32_t) dmabuf_out, data_len);
|
||||
|
||||
// Start enc/dec.
|
||||
// NOTE: Don't call driver function TDES_Start in BSP because it will override TDES_CTL[3KEYS] setting.
|
||||
CRPT->TDES_CTL |= CRPT_TDES_CTL_START_Msk | (CRYPTO_DMA_ONE_SHOT << CRPT_TDES_CTL_DMALAST_Pos);
|
||||
while (CRPT->TDES_STS & CRPT_TDES_STS_BUSY_Msk);
|
||||
|
||||
memcpy(out_pos, dmabuf_out, data_len);
|
||||
in_pos += data_len;
|
||||
out_pos += data_len;
|
||||
rmn -= data_len;
|
||||
|
||||
// Update IV for next block enc/dec in next function call
|
||||
switch (tdes_opmode) {
|
||||
case DES_MODE_OFB:
|
||||
case TDES_MODE_OFB: {
|
||||
// OFB: IV (enc/dec) = output block XOR input block
|
||||
uint32_t lbh, lbl;
|
||||
// Last block of input data
|
||||
lbh = nu_get32_be(dmabuf_in + data_len - 8 + 4);
|
||||
lbl = nu_get32_be(dmabuf_in + data_len - 8 + 0);
|
||||
// Last block of output data
|
||||
ivh = nu_get32_be(dmabuf_out + 4);
|
||||
ivl = nu_get32_be(dmabuf_out + 0);
|
||||
ivh = ivh ^ lbh;
|
||||
ivl = ivl ^ lbl;
|
||||
nu_set32_be(iv + 4, ivh);
|
||||
nu_set32_be(iv, ivl);
|
||||
break;
|
||||
}
|
||||
case DES_MODE_CBC:
|
||||
case DES_MODE_CFB:
|
||||
case TDES_MODE_CBC:
|
||||
case TDES_MODE_CFB: {
|
||||
// CBC/CFB: IV (enc) = output block
|
||||
// IV (dec) = input block
|
||||
if (enc) {
|
||||
memcpy(iv, dmabuf_out + data_len - 8, 8);
|
||||
}
|
||||
else {
|
||||
memcpy(iv, dmabuf_in + data_len - 8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_DES_ALT */
|
||||
#endif /* MBEDTLS_DES_C */
|
|
@ -0,0 +1,279 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015-2016 Nuvoton
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_DES_ALT_H
|
||||
#define MBEDTLS_DES_ALT_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_DES_ALT)
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "des.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief DES context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int enc; /*!< 0: dec, 1: enc */
|
||||
uint16_t keyopt;
|
||||
uint8_t key[3][MBEDTLS_DES_KEY_SIZE]; /*!< 3DES keys */
|
||||
}
|
||||
mbedtls_des_context;
|
||||
|
||||
/**
|
||||
* \brief Triple-DES context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int enc; /*!< 0: dec, 1: enc */
|
||||
uint16_t keyopt;
|
||||
uint8_t key[3][MBEDTLS_DES_KEY_SIZE]; /*!< 3DES keys */
|
||||
}
|
||||
mbedtls_des3_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize DES context
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
*/
|
||||
void mbedtls_des_init( mbedtls_des_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear DES context
|
||||
*
|
||||
* \param ctx DES context to be cleared
|
||||
*/
|
||||
void mbedtls_des_free( mbedtls_des_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Initialize Triple-DES context
|
||||
*
|
||||
* \param ctx DES3 context to be initialized
|
||||
*/
|
||||
void mbedtls_des3_init( mbedtls_des3_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear Triple-DES context
|
||||
*
|
||||
* \param ctx DES3 context to be cleared
|
||||
*/
|
||||
void mbedtls_des3_free( mbedtls_des3_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Set key parity on the given key to odd.
|
||||
*
|
||||
* DES keys are 56 bits long, but each byte is padded with
|
||||
* a parity bit to allow verification.
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*/
|
||||
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief Check that key parity on the given key is odd.
|
||||
*
|
||||
* DES keys are 56 bits long, but each byte is padded with
|
||||
* a parity bit to allow verification.
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0 is parity was ok, 1 if parity was not correct.
|
||||
*/
|
||||
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief Check that key is not a weak or semi-weak DES key
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0 if no weak key was found, 1 if a weak key was identified.
|
||||
*/
|
||||
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief DES key schedule (56-bit, encryption)
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief DES key schedule (56-bit, decryption)
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (112-bit, encryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 16-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (112-bit, decryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 16-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (168-bit, encryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 24-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (168-bit, decryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 24-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
|
||||
|
||||
/**
|
||||
* \brief DES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx DES context
|
||||
* \param input 64-bit input block
|
||||
* \param output 64-bit output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] );
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief DES-CBC buffer encryption/decryption
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx DES context
|
||||
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*/
|
||||
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
/**
|
||||
* \brief 3DES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx 3DES context
|
||||
* \param input 64-bit input block
|
||||
* \param output 64-bit output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8] );
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief 3DES-CBC buffer encryption/decryption
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx 3DES context
|
||||
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
/**
|
||||
* \brief Internal function for key expansion.
|
||||
* (Only exposed to allow overriding it,
|
||||
* see MBEDTLS_DES_SETKEY_ALT)
|
||||
*
|
||||
* \param SK Round keys
|
||||
* \param key Base key
|
||||
*/
|
||||
void mbedtls_des_setkey( uint32_t SK[32],
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_DES_ALT */
|
||||
|
||||
#endif /* des_alt.h */
|
Loading…
Reference in New Issue