2021-07-19 21:55:20 +00:00
|
|
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
|
|
|
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
│ Copyright The Mbed TLS Contributors │
|
|
|
|
│ │
|
|
|
|
│ 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. │
|
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
2023-05-12 04:53:15 +00:00
|
|
|
#include "third_party/mbedtls/des.h"
|
2021-10-02 13:17:17 +00:00
|
|
|
#include "libc/mem/mem.h"
|
2021-06-24 19:31:26 +00:00
|
|
|
#include "libc/stdio/stdio.h"
|
|
|
|
#include "libc/str/str.h"
|
|
|
|
#include "third_party/mbedtls/common.h"
|
|
|
|
#include "third_party/mbedtls/endian.h"
|
|
|
|
#include "third_party/mbedtls/platform.h"
|
Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.
This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.
Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.
OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().
This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.
We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
|
|
|
__static_yoink("mbedtls_notice");
|
2021-07-19 21:55:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @fileoverview FIPS-46-3 compliant Triple-DES implementation
|
2021-06-15 18:39:36 +00:00
|
|
|
*
|
2021-07-19 21:55:20 +00:00
|
|
|
* DES, on which TDES is based, was originally designed by Horst Feistel
|
|
|
|
* at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
|
2021-08-04 05:42:17 +00:00
|
|
|
* NIST calls this DEA. The true name of this algorithm is Lucifer.
|
2021-06-15 18:39:36 +00:00
|
|
|
*
|
2021-07-19 21:55:20 +00:00
|
|
|
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
|
2021-06-15 18:39:36 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Expanded DES S-boxes
|
|
|
|
*/
|
|
|
|
static const uint32_t SB1[64] =
|
|
|
|
{
|
|
|
|
0x01010400, 0x00000000, 0x00010000, 0x01010404,
|
|
|
|
0x01010004, 0x00010404, 0x00000004, 0x00010000,
|
|
|
|
0x00000400, 0x01010400, 0x01010404, 0x00000400,
|
|
|
|
0x01000404, 0x01010004, 0x01000000, 0x00000004,
|
|
|
|
0x00000404, 0x01000400, 0x01000400, 0x00010400,
|
|
|
|
0x00010400, 0x01010000, 0x01010000, 0x01000404,
|
|
|
|
0x00010004, 0x01000004, 0x01000004, 0x00010004,
|
|
|
|
0x00000000, 0x00000404, 0x00010404, 0x01000000,
|
|
|
|
0x00010000, 0x01010404, 0x00000004, 0x01010000,
|
|
|
|
0x01010400, 0x01000000, 0x01000000, 0x00000400,
|
|
|
|
0x01010004, 0x00010000, 0x00010400, 0x01000004,
|
|
|
|
0x00000400, 0x00000004, 0x01000404, 0x00010404,
|
|
|
|
0x01010404, 0x00010004, 0x01010000, 0x01000404,
|
|
|
|
0x01000004, 0x00000404, 0x00010404, 0x01010400,
|
|
|
|
0x00000404, 0x01000400, 0x01000400, 0x00000000,
|
|
|
|
0x00010004, 0x00010400, 0x00000000, 0x01010004
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t SB2[64] =
|
|
|
|
{
|
|
|
|
0x80108020, 0x80008000, 0x00008000, 0x00108020,
|
|
|
|
0x00100000, 0x00000020, 0x80100020, 0x80008020,
|
|
|
|
0x80000020, 0x80108020, 0x80108000, 0x80000000,
|
|
|
|
0x80008000, 0x00100000, 0x00000020, 0x80100020,
|
|
|
|
0x00108000, 0x00100020, 0x80008020, 0x00000000,
|
|
|
|
0x80000000, 0x00008000, 0x00108020, 0x80100000,
|
|
|
|
0x00100020, 0x80000020, 0x00000000, 0x00108000,
|
|
|
|
0x00008020, 0x80108000, 0x80100000, 0x00008020,
|
|
|
|
0x00000000, 0x00108020, 0x80100020, 0x00100000,
|
|
|
|
0x80008020, 0x80100000, 0x80108000, 0x00008000,
|
|
|
|
0x80100000, 0x80008000, 0x00000020, 0x80108020,
|
|
|
|
0x00108020, 0x00000020, 0x00008000, 0x80000000,
|
|
|
|
0x00008020, 0x80108000, 0x00100000, 0x80000020,
|
|
|
|
0x00100020, 0x80008020, 0x80000020, 0x00100020,
|
|
|
|
0x00108000, 0x00000000, 0x80008000, 0x00008020,
|
|
|
|
0x80000000, 0x80100020, 0x80108020, 0x00108000
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t SB3[64] =
|
|
|
|
{
|
|
|
|
0x00000208, 0x08020200, 0x00000000, 0x08020008,
|
|
|
|
0x08000200, 0x00000000, 0x00020208, 0x08000200,
|
|
|
|
0x00020008, 0x08000008, 0x08000008, 0x00020000,
|
|
|
|
0x08020208, 0x00020008, 0x08020000, 0x00000208,
|
|
|
|
0x08000000, 0x00000008, 0x08020200, 0x00000200,
|
|
|
|
0x00020200, 0x08020000, 0x08020008, 0x00020208,
|
|
|
|
0x08000208, 0x00020200, 0x00020000, 0x08000208,
|
|
|
|
0x00000008, 0x08020208, 0x00000200, 0x08000000,
|
|
|
|
0x08020200, 0x08000000, 0x00020008, 0x00000208,
|
|
|
|
0x00020000, 0x08020200, 0x08000200, 0x00000000,
|
|
|
|
0x00000200, 0x00020008, 0x08020208, 0x08000200,
|
|
|
|
0x08000008, 0x00000200, 0x00000000, 0x08020008,
|
|
|
|
0x08000208, 0x00020000, 0x08000000, 0x08020208,
|
|
|
|
0x00000008, 0x00020208, 0x00020200, 0x08000008,
|
|
|
|
0x08020000, 0x08000208, 0x00000208, 0x08020000,
|
|
|
|
0x00020208, 0x00000008, 0x08020008, 0x00020200
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t SB4[64] =
|
|
|
|
{
|
|
|
|
0x00802001, 0x00002081, 0x00002081, 0x00000080,
|
|
|
|
0x00802080, 0x00800081, 0x00800001, 0x00002001,
|
|
|
|
0x00000000, 0x00802000, 0x00802000, 0x00802081,
|
|
|
|
0x00000081, 0x00000000, 0x00800080, 0x00800001,
|
|
|
|
0x00000001, 0x00002000, 0x00800000, 0x00802001,
|
|
|
|
0x00000080, 0x00800000, 0x00002001, 0x00002080,
|
|
|
|
0x00800081, 0x00000001, 0x00002080, 0x00800080,
|
|
|
|
0x00002000, 0x00802080, 0x00802081, 0x00000081,
|
|
|
|
0x00800080, 0x00800001, 0x00802000, 0x00802081,
|
|
|
|
0x00000081, 0x00000000, 0x00000000, 0x00802000,
|
|
|
|
0x00002080, 0x00800080, 0x00800081, 0x00000001,
|
|
|
|
0x00802001, 0x00002081, 0x00002081, 0x00000080,
|
|
|
|
0x00802081, 0x00000081, 0x00000001, 0x00002000,
|
|
|
|
0x00800001, 0x00002001, 0x00802080, 0x00800081,
|
|
|
|
0x00002001, 0x00002080, 0x00800000, 0x00802001,
|
|
|
|
0x00000080, 0x00800000, 0x00002000, 0x00802080
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t SB5[64] =
|
|
|
|
{
|
|
|
|
0x00000100, 0x02080100, 0x02080000, 0x42000100,
|
|
|
|
0x00080000, 0x00000100, 0x40000000, 0x02080000,
|
|
|
|
0x40080100, 0x00080000, 0x02000100, 0x40080100,
|
|
|
|
0x42000100, 0x42080000, 0x00080100, 0x40000000,
|
|
|
|
0x02000000, 0x40080000, 0x40080000, 0x00000000,
|
|
|
|
0x40000100, 0x42080100, 0x42080100, 0x02000100,
|
|
|
|
0x42080000, 0x40000100, 0x00000000, 0x42000000,
|
|
|
|
0x02080100, 0x02000000, 0x42000000, 0x00080100,
|
|
|
|
0x00080000, 0x42000100, 0x00000100, 0x02000000,
|
|
|
|
0x40000000, 0x02080000, 0x42000100, 0x40080100,
|
|
|
|
0x02000100, 0x40000000, 0x42080000, 0x02080100,
|
|
|
|
0x40080100, 0x00000100, 0x02000000, 0x42080000,
|
|
|
|
0x42080100, 0x00080100, 0x42000000, 0x42080100,
|
|
|
|
0x02080000, 0x00000000, 0x40080000, 0x42000000,
|
|
|
|
0x00080100, 0x02000100, 0x40000100, 0x00080000,
|
|
|
|
0x00000000, 0x40080000, 0x02080100, 0x40000100
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t SB6[64] =
|
|
|
|
{
|
|
|
|
0x20000010, 0x20400000, 0x00004000, 0x20404010,
|
|
|
|
0x20400000, 0x00000010, 0x20404010, 0x00400000,
|
|
|
|
0x20004000, 0x00404010, 0x00400000, 0x20000010,
|
|
|
|
0x00400010, 0x20004000, 0x20000000, 0x00004010,
|
|
|
|
0x00000000, 0x00400010, 0x20004010, 0x00004000,
|
|
|
|
0x00404000, 0x20004010, 0x00000010, 0x20400010,
|
|
|
|
0x20400010, 0x00000000, 0x00404010, 0x20404000,
|
|
|
|
0x00004010, 0x00404000, 0x20404000, 0x20000000,
|
|
|
|
0x20004000, 0x00000010, 0x20400010, 0x00404000,
|
|
|
|
0x20404010, 0x00400000, 0x00004010, 0x20000010,
|
|
|
|
0x00400000, 0x20004000, 0x20000000, 0x00004010,
|
|
|
|
0x20000010, 0x20404010, 0x00404000, 0x20400000,
|
|
|
|
0x00404010, 0x20404000, 0x00000000, 0x20400010,
|
|
|
|
0x00000010, 0x00004000, 0x20400000, 0x00404010,
|
|
|
|
0x00004000, 0x00400010, 0x20004010, 0x00000000,
|
|
|
|
0x20404000, 0x20000000, 0x00400010, 0x20004010
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t SB7[64] =
|
|
|
|
{
|
|
|
|
0x00200000, 0x04200002, 0x04000802, 0x00000000,
|
|
|
|
0x00000800, 0x04000802, 0x00200802, 0x04200800,
|
|
|
|
0x04200802, 0x00200000, 0x00000000, 0x04000002,
|
|
|
|
0x00000002, 0x04000000, 0x04200002, 0x00000802,
|
|
|
|
0x04000800, 0x00200802, 0x00200002, 0x04000800,
|
|
|
|
0x04000002, 0x04200000, 0x04200800, 0x00200002,
|
|
|
|
0x04200000, 0x00000800, 0x00000802, 0x04200802,
|
|
|
|
0x00200800, 0x00000002, 0x04000000, 0x00200800,
|
|
|
|
0x04000000, 0x00200800, 0x00200000, 0x04000802,
|
|
|
|
0x04000802, 0x04200002, 0x04200002, 0x00000002,
|
|
|
|
0x00200002, 0x04000000, 0x04000800, 0x00200000,
|
|
|
|
0x04200800, 0x00000802, 0x00200802, 0x04200800,
|
|
|
|
0x00000802, 0x04000002, 0x04200802, 0x04200000,
|
|
|
|
0x00200800, 0x00000000, 0x00000002, 0x04200802,
|
|
|
|
0x00000000, 0x00200802, 0x04200000, 0x00000800,
|
|
|
|
0x04000002, 0x04000800, 0x00000800, 0x00200002
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t SB8[64] =
|
|
|
|
{
|
|
|
|
0x10001040, 0x00001000, 0x00040000, 0x10041040,
|
|
|
|
0x10000000, 0x10001040, 0x00000040, 0x10000000,
|
|
|
|
0x00040040, 0x10040000, 0x10041040, 0x00041000,
|
|
|
|
0x10041000, 0x00041040, 0x00001000, 0x00000040,
|
|
|
|
0x10040000, 0x10000040, 0x10001000, 0x00001040,
|
|
|
|
0x00041000, 0x00040040, 0x10040040, 0x10041000,
|
|
|
|
0x00001040, 0x00000000, 0x00000000, 0x10040040,
|
|
|
|
0x10000040, 0x10001000, 0x00041040, 0x00040000,
|
|
|
|
0x00041040, 0x00040000, 0x10041000, 0x00001000,
|
|
|
|
0x00000040, 0x10040040, 0x00001000, 0x00041040,
|
|
|
|
0x10001000, 0x00000040, 0x10000040, 0x10040000,
|
|
|
|
0x10040040, 0x10000000, 0x00040000, 0x10001040,
|
|
|
|
0x00000000, 0x10041040, 0x00040040, 0x10000040,
|
|
|
|
0x10040000, 0x10001000, 0x10001040, 0x00000000,
|
|
|
|
0x10041040, 0x00041000, 0x00041000, 0x00001040,
|
|
|
|
0x00001040, 0x00040040, 0x10000000, 0x10041000
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PC1: left and right halves bit-swap
|
|
|
|
*/
|
|
|
|
static const uint32_t LHs[16] =
|
|
|
|
{
|
|
|
|
0x00000000, 0x00000001, 0x00000100, 0x00000101,
|
|
|
|
0x00010000, 0x00010001, 0x00010100, 0x00010101,
|
|
|
|
0x01000000, 0x01000001, 0x01000100, 0x01000101,
|
|
|
|
0x01010000, 0x01010001, 0x01010100, 0x01010101
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t RHs[16] =
|
|
|
|
{
|
|
|
|
0x00000000, 0x01000000, 0x00010000, 0x01010000,
|
|
|
|
0x00000100, 0x01000100, 0x00010100, 0x01010100,
|
|
|
|
0x00000001, 0x01000001, 0x00010001, 0x01010001,
|
|
|
|
0x00000101, 0x01000101, 0x00010101, 0x01010101,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initial Permutation macro
|
|
|
|
*/
|
|
|
|
#define DES_IP(X,Y) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
|
|
|
|
T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
|
|
|
|
T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
|
|
|
|
T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
|
|
|
|
(Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
|
|
|
|
T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
|
|
|
|
(X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
|
|
|
|
} while( 0 )
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Final Permutation macro
|
|
|
|
*/
|
|
|
|
#define DES_FP(X,Y) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
(X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
|
|
|
|
T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
|
|
|
|
(Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
|
|
|
|
T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
|
|
|
|
T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
|
|
|
|
T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
|
|
|
|
T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
|
|
|
|
} while( 0 )
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DES round macro
|
|
|
|
*/
|
|
|
|
#define DES_ROUND(X,Y) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
T = *SK++ ^ (X); \
|
|
|
|
(Y) ^= SB8[ (T ) & 0x3F ] ^ \
|
|
|
|
SB6[ (T >> 8) & 0x3F ] ^ \
|
|
|
|
SB4[ (T >> 16) & 0x3F ] ^ \
|
|
|
|
SB2[ (T >> 24) & 0x3F ]; \
|
|
|
|
\
|
|
|
|
T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
|
|
|
|
(Y) ^= SB7[ (T ) & 0x3F ] ^ \
|
|
|
|
SB5[ (T >> 8) & 0x3F ] ^ \
|
|
|
|
SB3[ (T >> 16) & 0x3F ] ^ \
|
|
|
|
SB1[ (T >> 24) & 0x3F ]; \
|
|
|
|
} while( 0 )
|
|
|
|
|
|
|
|
#define SWAP(a,b) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
|
|
|
|
} while( 0 )
|
|
|
|
|
|
|
|
void mbedtls_des_init( mbedtls_des_context *ctx )
|
|
|
|
{
|
2021-07-19 21:55:20 +00:00
|
|
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
|
2021-06-15 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mbedtls_des_free( mbedtls_des_context *ctx )
|
|
|
|
{
|
|
|
|
if( ctx == NULL )
|
|
|
|
return;
|
|
|
|
|
|
|
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void mbedtls_des3_init( mbedtls_des3_context *ctx )
|
|
|
|
{
|
2021-07-19 21:55:20 +00:00
|
|
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
|
2021-06-15 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mbedtls_des3_free( mbedtls_des3_context *ctx )
|
|
|
|
{
|
|
|
|
if( ctx == NULL )
|
|
|
|
return;
|
|
|
|
|
|
|
|
mbedtls_platform_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++ )
|
2021-09-28 05:58:51 +00:00
|
|
|
if( timingsafe_bcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
|
2021-06-15 18:39:36 +00:00
|
|
|
return( 1 );
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(MBEDTLS_DES_SETKEY_ALT)
|
|
|
|
void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint32_t X, Y, T;
|
|
|
|
|
|
|
|
GET_UINT32_BE( X, key, 0 );
|
|
|
|
GET_UINT32_BE( Y, key, 4 );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Permuted Choice 1
|
|
|
|
*/
|
|
|
|
T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
|
|
|
|
T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
|
|
|
|
|
|
|
|
X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
|
|
|
|
| (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
|
|
|
|
| (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
|
|
|
|
| (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
|
|
|
|
|
|
|
|
Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
|
|
|
|
| (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
|
|
|
|
| (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
|
|
|
|
| (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
|
|
|
|
|
|
|
|
X &= 0x0FFFFFFF;
|
|
|
|
Y &= 0x0FFFFFFF;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* calculate subkeys
|
|
|
|
*/
|
|
|
|
for( i = 0; i < 16; i++ )
|
|
|
|
{
|
|
|
|
if( i < 2 || i == 8 || i == 15 )
|
|
|
|
{
|
|
|
|
X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
|
|
|
|
Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
|
|
|
|
Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
*SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
|
|
|
|
| ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
|
|
|
|
| ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
|
|
|
|
| ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
|
|
|
|
| ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
|
|
|
|
| ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
|
|
|
|
| ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
|
|
|
|
| ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
|
|
|
|
| ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
|
|
|
|
| ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
|
|
|
|
| ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
|
|
|
|
|
|
|
|
*SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
|
|
|
|
| ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
|
|
|
|
| ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
|
|
|
|
| ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
|
|
|
|
| ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
|
|
|
|
| ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
|
|
|
|
| ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
|
|
|
|
| ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
|
|
|
|
| ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
|
|
|
|
| ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
|
|
|
|
| ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* !MBEDTLS_DES_SETKEY_ALT */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DES key schedule (56-bit, encryption)
|
|
|
|
*/
|
|
|
|
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
|
|
|
|
{
|
|
|
|
mbedtls_des_setkey( ctx->sk, key );
|
|
|
|
|
|
|
|
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] )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
mbedtls_des_setkey( ctx->sk, key );
|
|
|
|
|
|
|
|
for( i = 0; i < 16; i += 2 )
|
|
|
|
{
|
|
|
|
SWAP( ctx->sk[i ], ctx->sk[30 - i] );
|
|
|
|
SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
|
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void des3_set2key( uint32_t esk[96],
|
|
|
|
uint32_t dsk[96],
|
|
|
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
mbedtls_des_setkey( esk, key );
|
|
|
|
mbedtls_des_setkey( dsk + 32, key + 8 );
|
|
|
|
|
|
|
|
for( i = 0; i < 32; i += 2 )
|
|
|
|
{
|
|
|
|
dsk[i ] = esk[30 - i];
|
|
|
|
dsk[i + 1] = esk[31 - i];
|
|
|
|
|
|
|
|
esk[i + 32] = dsk[62 - i];
|
|
|
|
esk[i + 33] = dsk[63 - i];
|
|
|
|
|
|
|
|
esk[i + 64] = esk[i ];
|
|
|
|
esk[i + 65] = esk[i + 1];
|
|
|
|
|
|
|
|
dsk[i + 64] = dsk[i ];
|
|
|
|
dsk[i + 65] = dsk[i + 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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] )
|
|
|
|
{
|
|
|
|
uint32_t sk[96];
|
|
|
|
|
|
|
|
des3_set2key( ctx->sk, sk, key );
|
|
|
|
mbedtls_platform_zeroize( sk, sizeof( sk ) );
|
|
|
|
|
|
|
|
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] )
|
|
|
|
{
|
|
|
|
uint32_t sk[96];
|
|
|
|
|
|
|
|
des3_set2key( sk, ctx->sk, key );
|
|
|
|
mbedtls_platform_zeroize( sk, sizeof( sk ) );
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void des3_set3key( uint32_t esk[96],
|
|
|
|
uint32_t dsk[96],
|
|
|
|
const unsigned char key[24] )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
mbedtls_des_setkey( esk, key );
|
|
|
|
mbedtls_des_setkey( dsk + 32, key + 8 );
|
|
|
|
mbedtls_des_setkey( esk + 64, key + 16 );
|
|
|
|
|
|
|
|
for( i = 0; i < 32; i += 2 )
|
|
|
|
{
|
|
|
|
dsk[i ] = esk[94 - i];
|
|
|
|
dsk[i + 1] = esk[95 - i];
|
|
|
|
|
|
|
|
esk[i + 32] = dsk[62 - i];
|
|
|
|
esk[i + 33] = dsk[63 - i];
|
|
|
|
|
|
|
|
dsk[i + 64] = esk[30 - i];
|
|
|
|
dsk[i + 65] = esk[31 - i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Triple-DES key schedule (168-bit, encryption)
|
|
|
|
*/
|
|
|
|
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
|
2021-08-12 07:42:14 +00:00
|
|
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
uint32_t sk[96];
|
|
|
|
|
|
|
|
des3_set3key( ctx->sk, sk, key );
|
|
|
|
mbedtls_platform_zeroize( sk, sizeof( sk ) );
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Triple-DES key schedule (168-bit, decryption)
|
|
|
|
*/
|
|
|
|
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
|
2021-08-12 07:42:14 +00:00
|
|
|
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
uint32_t sk[96];
|
|
|
|
|
|
|
|
des3_set3key( sk, ctx->sk, key );
|
|
|
|
mbedtls_platform_zeroize( sk, sizeof( sk ) );
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DES-ECB block encryption/decryption
|
|
|
|
*/
|
|
|
|
#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
|
|
|
|
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
|
2021-08-12 07:42:14 +00:00
|
|
|
const unsigned char input[8],
|
|
|
|
unsigned char output[8] )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint32_t X, Y, T, *SK;
|
|
|
|
|
|
|
|
SK = ctx->sk;
|
|
|
|
|
|
|
|
GET_UINT32_BE( X, input, 0 );
|
|
|
|
GET_UINT32_BE( Y, input, 4 );
|
|
|
|
|
|
|
|
DES_IP( X, Y );
|
|
|
|
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
{
|
|
|
|
DES_ROUND( Y, X );
|
|
|
|
DES_ROUND( X, Y );
|
|
|
|
}
|
|
|
|
|
|
|
|
DES_FP( Y, X );
|
|
|
|
|
|
|
|
PUT_UINT32_BE( Y, output, 0 );
|
|
|
|
PUT_UINT32_BE( X, output, 4 );
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
|
|
/*
|
|
|
|
* DES-CBC buffer encryption/decryption
|
|
|
|
*/
|
|
|
|
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
|
2021-08-12 07:42:14 +00:00
|
|
|
int mode,
|
|
|
|
size_t length,
|
|
|
|
unsigned char iv[8],
|
|
|
|
const unsigned char *input,
|
|
|
|
unsigned char *output )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
unsigned char temp[8];
|
|
|
|
|
|
|
|
if( length % 8 )
|
|
|
|
return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
|
|
|
|
|
|
|
|
if( mode == MBEDTLS_DES_ENCRYPT )
|
|
|
|
{
|
|
|
|
while( length > 0 )
|
|
|
|
{
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
output[i] = (unsigned char)( input[i] ^ iv[i] );
|
|
|
|
|
|
|
|
mbedtls_des_crypt_ecb( ctx, output, output );
|
|
|
|
memcpy( iv, output, 8 );
|
|
|
|
|
|
|
|
input += 8;
|
|
|
|
output += 8;
|
|
|
|
length -= 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* MBEDTLS_DES_DECRYPT */
|
|
|
|
{
|
|
|
|
while( length > 0 )
|
|
|
|
{
|
|
|
|
memcpy( temp, input, 8 );
|
|
|
|
mbedtls_des_crypt_ecb( ctx, input, output );
|
|
|
|
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
|
|
|
|
|
|
|
memcpy( iv, temp, 8 );
|
|
|
|
|
|
|
|
input += 8;
|
|
|
|
output += 8;
|
|
|
|
length -= 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 3DES-ECB block encryption/decryption
|
|
|
|
*/
|
|
|
|
#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
|
|
|
|
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
|
2021-08-12 07:42:14 +00:00
|
|
|
const unsigned char input[8],
|
|
|
|
unsigned char output[8] )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint32_t X, Y, T, *SK;
|
|
|
|
|
|
|
|
SK = ctx->sk;
|
|
|
|
|
|
|
|
GET_UINT32_BE( X, input, 0 );
|
|
|
|
GET_UINT32_BE( Y, input, 4 );
|
|
|
|
|
|
|
|
DES_IP( X, Y );
|
|
|
|
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
{
|
|
|
|
DES_ROUND( Y, X );
|
|
|
|
DES_ROUND( X, Y );
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
{
|
|
|
|
DES_ROUND( X, Y );
|
|
|
|
DES_ROUND( Y, X );
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
{
|
|
|
|
DES_ROUND( Y, X );
|
|
|
|
DES_ROUND( X, Y );
|
|
|
|
}
|
|
|
|
|
|
|
|
DES_FP( Y, X );
|
|
|
|
|
|
|
|
PUT_UINT32_BE( Y, output, 0 );
|
|
|
|
PUT_UINT32_BE( X, output, 4 );
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
|
|
/*
|
|
|
|
* 3DES-CBC buffer encryption/decryption
|
|
|
|
*/
|
|
|
|
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
|
2021-08-12 07:42:14 +00:00
|
|
|
int mode,
|
|
|
|
size_t length,
|
|
|
|
unsigned char iv[8],
|
|
|
|
const unsigned char *input,
|
|
|
|
unsigned char *output )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
unsigned char temp[8];
|
|
|
|
|
|
|
|
if( length % 8 )
|
|
|
|
return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
|
|
|
|
|
|
|
|
if( mode == MBEDTLS_DES_ENCRYPT )
|
|
|
|
{
|
|
|
|
while( length > 0 )
|
|
|
|
{
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
output[i] = (unsigned char)( input[i] ^ iv[i] );
|
|
|
|
|
|
|
|
mbedtls_des3_crypt_ecb( ctx, output, output );
|
|
|
|
memcpy( iv, output, 8 );
|
|
|
|
|
|
|
|
input += 8;
|
|
|
|
output += 8;
|
|
|
|
length -= 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* MBEDTLS_DES_DECRYPT */
|
|
|
|
{
|
|
|
|
while( length > 0 )
|
|
|
|
{
|
|
|
|
memcpy( temp, input, 8 );
|
|
|
|
mbedtls_des3_crypt_ecb( ctx, input, output );
|
|
|
|
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
|
|
|
|
|
|
|
memcpy( iv, temp, 8 );
|
|
|
|
|
|
|
|
input += 8;
|
|
|
|
output += 8;
|
|
|
|
length -= 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_SELF_TEST)
|
|
|
|
/*
|
|
|
|
* DES and 3DES test vectors from:
|
|
|
|
*
|
|
|
|
* http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
|
|
|
|
*/
|
|
|
|
static const unsigned char des3_test_keys[24] =
|
|
|
|
{
|
|
|
|
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
|
|
|
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
|
|
|
|
0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
|
|
|
|
};
|
|
|
|
|
|
|
|
static const unsigned char des3_test_buf[8] =
|
|
|
|
{
|
|
|
|
0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
|
|
|
|
};
|
|
|
|
|
|
|
|
static const unsigned char des3_test_ecb_dec[3][8] =
|
|
|
|
{
|
|
|
|
{ 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
|
|
|
|
{ 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
|
|
|
|
{ 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const unsigned char des3_test_ecb_enc[3][8] =
|
|
|
|
{
|
|
|
|
{ 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
|
|
|
|
{ 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
|
|
|
|
{ 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
|
|
|
|
};
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
|
|
static const unsigned char des3_test_iv[8] =
|
|
|
|
{
|
|
|
|
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const unsigned char des3_test_cbc_dec[3][8] =
|
|
|
|
{
|
|
|
|
{ 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
|
|
|
|
{ 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
|
|
|
|
{ 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const unsigned char des3_test_cbc_enc[3][8] =
|
|
|
|
{
|
|
|
|
{ 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
|
|
|
|
{ 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
|
|
|
|
{ 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
|
|
|
|
};
|
|
|
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
|
|
|
|
2023-05-12 04:53:15 +00:00
|
|
|
static int mbedtls_des_self_test_impl( int verbose,
|
|
|
|
mbedtls_des_context *ctx,
|
|
|
|
mbedtls_des3_context *ctx3 )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
int i, j, u, v, ret = 0;
|
|
|
|
unsigned char buf[8];
|
|
|
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
|
|
unsigned char prv[8];
|
|
|
|
unsigned char iv[8];
|
|
|
|
#endif
|
|
|
|
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_init( ctx );
|
|
|
|
mbedtls_des3_init( ctx3 );
|
2021-06-15 18:39:36 +00:00
|
|
|
/*
|
|
|
|
* ECB mode
|
|
|
|
*/
|
|
|
|
for( i = 0; i < 6; i++ )
|
|
|
|
{
|
|
|
|
u = i >> 1;
|
|
|
|
v = i & 1;
|
|
|
|
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( " DES%c-ECB-%3d (%s): ",
|
|
|
|
( u == 0 ) ? ' ' : '3', 56 + u * 56,
|
|
|
|
( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
|
|
|
|
|
|
|
|
memcpy( buf, des3_test_buf, 8 );
|
|
|
|
|
|
|
|
switch( i )
|
|
|
|
{
|
|
|
|
case 0:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_setkey_dec( ctx, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_setkey_enc( ctx, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set2key_dec( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set2key_enc( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set3key_dec( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 5:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set3key_enc( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
for( j = 0; j < 100; j++ )
|
|
|
|
{
|
|
|
|
if( u == 0 )
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_crypt_ecb( ctx, buf, buf );
|
2021-06-15 18:39:36 +00:00
|
|
|
else
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_crypt_ecb( ctx3, buf, buf );
|
2021-06-15 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( ( v == MBEDTLS_DES_DECRYPT &&
|
2021-09-28 05:58:51 +00:00
|
|
|
timingsafe_bcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
|
2021-06-15 18:39:36 +00:00
|
|
|
( v != MBEDTLS_DES_DECRYPT &&
|
2021-09-28 05:58:51 +00:00
|
|
|
timingsafe_bcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( "failed\n" );
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( "passed\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( "\n" );
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
|
|
/*
|
|
|
|
* CBC mode
|
|
|
|
*/
|
|
|
|
for( i = 0; i < 6; i++ )
|
|
|
|
{
|
|
|
|
u = i >> 1;
|
|
|
|
v = i & 1;
|
|
|
|
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( " DES%c-CBC-%3d (%s): ",
|
|
|
|
( u == 0 ) ? ' ' : '3', 56 + u * 56,
|
|
|
|
( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
|
|
|
|
|
|
|
|
memcpy( iv, des3_test_iv, 8 );
|
|
|
|
memcpy( prv, des3_test_iv, 8 );
|
|
|
|
memcpy( buf, des3_test_buf, 8 );
|
|
|
|
|
|
|
|
switch( i )
|
|
|
|
{
|
|
|
|
case 0:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_setkey_dec( ctx, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_setkey_enc( ctx, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set2key_dec( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set2key_enc( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set3key_dec( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 5:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_set3key_enc( ctx3, des3_test_keys );
|
2021-06-15 18:39:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( v == MBEDTLS_DES_DECRYPT )
|
|
|
|
{
|
|
|
|
for( j = 0; j < 100; j++ )
|
|
|
|
{
|
|
|
|
if( u == 0 )
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_crypt_cbc( ctx, v, 8, iv, buf, buf );
|
2021-06-15 18:39:36 +00:00
|
|
|
else
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_crypt_cbc( ctx3, v, 8, iv, buf, buf );
|
2021-06-15 18:39:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for( j = 0; j < 100; j++ )
|
|
|
|
{
|
|
|
|
unsigned char tmp[8];
|
|
|
|
|
|
|
|
if( u == 0 )
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_crypt_cbc( ctx, v, 8, iv, buf, buf );
|
2021-06-15 18:39:36 +00:00
|
|
|
else
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des3_crypt_cbc( ctx3, v, 8, iv, buf, buf );
|
2021-06-15 18:39:36 +00:00
|
|
|
|
|
|
|
memcpy( tmp, prv, 8 );
|
|
|
|
memcpy( prv, buf, 8 );
|
|
|
|
memcpy( buf, tmp, 8 );
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy( buf, prv, 8 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ( v == MBEDTLS_DES_DECRYPT &&
|
2021-09-28 05:58:51 +00:00
|
|
|
timingsafe_bcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
|
2021-06-15 18:39:36 +00:00
|
|
|
( v != MBEDTLS_DES_DECRYPT &&
|
2021-09-28 05:58:51 +00:00
|
|
|
timingsafe_bcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
|
2021-06-15 18:39:36 +00:00
|
|
|
{
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( "failed\n" );
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( "passed\n" );
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
|
|
|
|
|
|
|
if( verbose != 0 )
|
|
|
|
mbedtls_printf( "\n" );
|
|
|
|
|
|
|
|
exit:
|
2021-10-02 13:17:17 +00:00
|
|
|
mbedtls_des_free( ctx );
|
|
|
|
mbedtls_des3_free( ctx3 );
|
2021-06-15 18:39:36 +00:00
|
|
|
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
2023-05-12 04:53:15 +00:00
|
|
|
int mbedtls_des_self_test( int verbose )
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
mbedtls_des_context *ctx;
|
|
|
|
mbedtls_des3_context *ctx3;
|
|
|
|
ctx = malloc( sizeof( mbedtls_des_context ) );
|
|
|
|
ctx3 = malloc( sizeof( mbedtls_des3_context ) );
|
|
|
|
rc = mbedtls_des_self_test_impl( verbose, ctx, ctx3 );
|
|
|
|
free( ctx3 );
|
|
|
|
free( ctx );
|
|
|
|
return( rc );
|
|
|
|
}
|
|
|
|
|
2021-06-15 18:39:36 +00:00
|
|
|
#endif /* MBEDTLS_SELF_TEST */
|