1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * FIPS-46-3 compliant Triple-DES implementation 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 6a8e1175bSopenharmony_ci * 7a8e1175bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); you may 8a8e1175bSopenharmony_ci * not use this file except in compliance with the License. 9a8e1175bSopenharmony_ci * You may obtain a copy of the License at 10a8e1175bSopenharmony_ci * 11a8e1175bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12a8e1175bSopenharmony_ci * 13a8e1175bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14a8e1175bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15a8e1175bSopenharmony_ci * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16a8e1175bSopenharmony_ci * See the License for the specific language governing permissions and 17a8e1175bSopenharmony_ci * limitations under the License. 18a8e1175bSopenharmony_ci */ 19a8e1175bSopenharmony_ci/* 20a8e1175bSopenharmony_ci * DES, on which TDES is based, was originally designed by Horst Feistel 21a8e1175bSopenharmony_ci * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). 22a8e1175bSopenharmony_ci * 23a8e1175bSopenharmony_ci * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf 24a8e1175bSopenharmony_ci */ 25a8e1175bSopenharmony_ci 26a8e1175bSopenharmony_ci#include "common.h" 27a8e1175bSopenharmony_ci 28a8e1175bSopenharmony_ci#if defined(MBEDTLS_DES_C) 29a8e1175bSopenharmony_ci 30a8e1175bSopenharmony_ci#include "mbedtls/des.h" 31a8e1175bSopenharmony_ci#include "mbedtls/error.h" 32a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 33a8e1175bSopenharmony_ci 34a8e1175bSopenharmony_ci#include <string.h> 35a8e1175bSopenharmony_ci 36a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 37a8e1175bSopenharmony_ci 38a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DES_ALT) 39a8e1175bSopenharmony_ci 40a8e1175bSopenharmony_ci/* 41a8e1175bSopenharmony_ci * Expanded DES S-boxes 42a8e1175bSopenharmony_ci */ 43a8e1175bSopenharmony_cistatic const uint32_t SB1[64] = 44a8e1175bSopenharmony_ci{ 45a8e1175bSopenharmony_ci 0x01010400, 0x00000000, 0x00010000, 0x01010404, 46a8e1175bSopenharmony_ci 0x01010004, 0x00010404, 0x00000004, 0x00010000, 47a8e1175bSopenharmony_ci 0x00000400, 0x01010400, 0x01010404, 0x00000400, 48a8e1175bSopenharmony_ci 0x01000404, 0x01010004, 0x01000000, 0x00000004, 49a8e1175bSopenharmony_ci 0x00000404, 0x01000400, 0x01000400, 0x00010400, 50a8e1175bSopenharmony_ci 0x00010400, 0x01010000, 0x01010000, 0x01000404, 51a8e1175bSopenharmony_ci 0x00010004, 0x01000004, 0x01000004, 0x00010004, 52a8e1175bSopenharmony_ci 0x00000000, 0x00000404, 0x00010404, 0x01000000, 53a8e1175bSopenharmony_ci 0x00010000, 0x01010404, 0x00000004, 0x01010000, 54a8e1175bSopenharmony_ci 0x01010400, 0x01000000, 0x01000000, 0x00000400, 55a8e1175bSopenharmony_ci 0x01010004, 0x00010000, 0x00010400, 0x01000004, 56a8e1175bSopenharmony_ci 0x00000400, 0x00000004, 0x01000404, 0x00010404, 57a8e1175bSopenharmony_ci 0x01010404, 0x00010004, 0x01010000, 0x01000404, 58a8e1175bSopenharmony_ci 0x01000004, 0x00000404, 0x00010404, 0x01010400, 59a8e1175bSopenharmony_ci 0x00000404, 0x01000400, 0x01000400, 0x00000000, 60a8e1175bSopenharmony_ci 0x00010004, 0x00010400, 0x00000000, 0x01010004 61a8e1175bSopenharmony_ci}; 62a8e1175bSopenharmony_ci 63a8e1175bSopenharmony_cistatic const uint32_t SB2[64] = 64a8e1175bSopenharmony_ci{ 65a8e1175bSopenharmony_ci 0x80108020, 0x80008000, 0x00008000, 0x00108020, 66a8e1175bSopenharmony_ci 0x00100000, 0x00000020, 0x80100020, 0x80008020, 67a8e1175bSopenharmony_ci 0x80000020, 0x80108020, 0x80108000, 0x80000000, 68a8e1175bSopenharmony_ci 0x80008000, 0x00100000, 0x00000020, 0x80100020, 69a8e1175bSopenharmony_ci 0x00108000, 0x00100020, 0x80008020, 0x00000000, 70a8e1175bSopenharmony_ci 0x80000000, 0x00008000, 0x00108020, 0x80100000, 71a8e1175bSopenharmony_ci 0x00100020, 0x80000020, 0x00000000, 0x00108000, 72a8e1175bSopenharmony_ci 0x00008020, 0x80108000, 0x80100000, 0x00008020, 73a8e1175bSopenharmony_ci 0x00000000, 0x00108020, 0x80100020, 0x00100000, 74a8e1175bSopenharmony_ci 0x80008020, 0x80100000, 0x80108000, 0x00008000, 75a8e1175bSopenharmony_ci 0x80100000, 0x80008000, 0x00000020, 0x80108020, 76a8e1175bSopenharmony_ci 0x00108020, 0x00000020, 0x00008000, 0x80000000, 77a8e1175bSopenharmony_ci 0x00008020, 0x80108000, 0x00100000, 0x80000020, 78a8e1175bSopenharmony_ci 0x00100020, 0x80008020, 0x80000020, 0x00100020, 79a8e1175bSopenharmony_ci 0x00108000, 0x00000000, 0x80008000, 0x00008020, 80a8e1175bSopenharmony_ci 0x80000000, 0x80100020, 0x80108020, 0x00108000 81a8e1175bSopenharmony_ci}; 82a8e1175bSopenharmony_ci 83a8e1175bSopenharmony_cistatic const uint32_t SB3[64] = 84a8e1175bSopenharmony_ci{ 85a8e1175bSopenharmony_ci 0x00000208, 0x08020200, 0x00000000, 0x08020008, 86a8e1175bSopenharmony_ci 0x08000200, 0x00000000, 0x00020208, 0x08000200, 87a8e1175bSopenharmony_ci 0x00020008, 0x08000008, 0x08000008, 0x00020000, 88a8e1175bSopenharmony_ci 0x08020208, 0x00020008, 0x08020000, 0x00000208, 89a8e1175bSopenharmony_ci 0x08000000, 0x00000008, 0x08020200, 0x00000200, 90a8e1175bSopenharmony_ci 0x00020200, 0x08020000, 0x08020008, 0x00020208, 91a8e1175bSopenharmony_ci 0x08000208, 0x00020200, 0x00020000, 0x08000208, 92a8e1175bSopenharmony_ci 0x00000008, 0x08020208, 0x00000200, 0x08000000, 93a8e1175bSopenharmony_ci 0x08020200, 0x08000000, 0x00020008, 0x00000208, 94a8e1175bSopenharmony_ci 0x00020000, 0x08020200, 0x08000200, 0x00000000, 95a8e1175bSopenharmony_ci 0x00000200, 0x00020008, 0x08020208, 0x08000200, 96a8e1175bSopenharmony_ci 0x08000008, 0x00000200, 0x00000000, 0x08020008, 97a8e1175bSopenharmony_ci 0x08000208, 0x00020000, 0x08000000, 0x08020208, 98a8e1175bSopenharmony_ci 0x00000008, 0x00020208, 0x00020200, 0x08000008, 99a8e1175bSopenharmony_ci 0x08020000, 0x08000208, 0x00000208, 0x08020000, 100a8e1175bSopenharmony_ci 0x00020208, 0x00000008, 0x08020008, 0x00020200 101a8e1175bSopenharmony_ci}; 102a8e1175bSopenharmony_ci 103a8e1175bSopenharmony_cistatic const uint32_t SB4[64] = 104a8e1175bSopenharmony_ci{ 105a8e1175bSopenharmony_ci 0x00802001, 0x00002081, 0x00002081, 0x00000080, 106a8e1175bSopenharmony_ci 0x00802080, 0x00800081, 0x00800001, 0x00002001, 107a8e1175bSopenharmony_ci 0x00000000, 0x00802000, 0x00802000, 0x00802081, 108a8e1175bSopenharmony_ci 0x00000081, 0x00000000, 0x00800080, 0x00800001, 109a8e1175bSopenharmony_ci 0x00000001, 0x00002000, 0x00800000, 0x00802001, 110a8e1175bSopenharmony_ci 0x00000080, 0x00800000, 0x00002001, 0x00002080, 111a8e1175bSopenharmony_ci 0x00800081, 0x00000001, 0x00002080, 0x00800080, 112a8e1175bSopenharmony_ci 0x00002000, 0x00802080, 0x00802081, 0x00000081, 113a8e1175bSopenharmony_ci 0x00800080, 0x00800001, 0x00802000, 0x00802081, 114a8e1175bSopenharmony_ci 0x00000081, 0x00000000, 0x00000000, 0x00802000, 115a8e1175bSopenharmony_ci 0x00002080, 0x00800080, 0x00800081, 0x00000001, 116a8e1175bSopenharmony_ci 0x00802001, 0x00002081, 0x00002081, 0x00000080, 117a8e1175bSopenharmony_ci 0x00802081, 0x00000081, 0x00000001, 0x00002000, 118a8e1175bSopenharmony_ci 0x00800001, 0x00002001, 0x00802080, 0x00800081, 119a8e1175bSopenharmony_ci 0x00002001, 0x00002080, 0x00800000, 0x00802001, 120a8e1175bSopenharmony_ci 0x00000080, 0x00800000, 0x00002000, 0x00802080 121a8e1175bSopenharmony_ci}; 122a8e1175bSopenharmony_ci 123a8e1175bSopenharmony_cistatic const uint32_t SB5[64] = 124a8e1175bSopenharmony_ci{ 125a8e1175bSopenharmony_ci 0x00000100, 0x02080100, 0x02080000, 0x42000100, 126a8e1175bSopenharmony_ci 0x00080000, 0x00000100, 0x40000000, 0x02080000, 127a8e1175bSopenharmony_ci 0x40080100, 0x00080000, 0x02000100, 0x40080100, 128a8e1175bSopenharmony_ci 0x42000100, 0x42080000, 0x00080100, 0x40000000, 129a8e1175bSopenharmony_ci 0x02000000, 0x40080000, 0x40080000, 0x00000000, 130a8e1175bSopenharmony_ci 0x40000100, 0x42080100, 0x42080100, 0x02000100, 131a8e1175bSopenharmony_ci 0x42080000, 0x40000100, 0x00000000, 0x42000000, 132a8e1175bSopenharmony_ci 0x02080100, 0x02000000, 0x42000000, 0x00080100, 133a8e1175bSopenharmony_ci 0x00080000, 0x42000100, 0x00000100, 0x02000000, 134a8e1175bSopenharmony_ci 0x40000000, 0x02080000, 0x42000100, 0x40080100, 135a8e1175bSopenharmony_ci 0x02000100, 0x40000000, 0x42080000, 0x02080100, 136a8e1175bSopenharmony_ci 0x40080100, 0x00000100, 0x02000000, 0x42080000, 137a8e1175bSopenharmony_ci 0x42080100, 0x00080100, 0x42000000, 0x42080100, 138a8e1175bSopenharmony_ci 0x02080000, 0x00000000, 0x40080000, 0x42000000, 139a8e1175bSopenharmony_ci 0x00080100, 0x02000100, 0x40000100, 0x00080000, 140a8e1175bSopenharmony_ci 0x00000000, 0x40080000, 0x02080100, 0x40000100 141a8e1175bSopenharmony_ci}; 142a8e1175bSopenharmony_ci 143a8e1175bSopenharmony_cistatic const uint32_t SB6[64] = 144a8e1175bSopenharmony_ci{ 145a8e1175bSopenharmony_ci 0x20000010, 0x20400000, 0x00004000, 0x20404010, 146a8e1175bSopenharmony_ci 0x20400000, 0x00000010, 0x20404010, 0x00400000, 147a8e1175bSopenharmony_ci 0x20004000, 0x00404010, 0x00400000, 0x20000010, 148a8e1175bSopenharmony_ci 0x00400010, 0x20004000, 0x20000000, 0x00004010, 149a8e1175bSopenharmony_ci 0x00000000, 0x00400010, 0x20004010, 0x00004000, 150a8e1175bSopenharmony_ci 0x00404000, 0x20004010, 0x00000010, 0x20400010, 151a8e1175bSopenharmony_ci 0x20400010, 0x00000000, 0x00404010, 0x20404000, 152a8e1175bSopenharmony_ci 0x00004010, 0x00404000, 0x20404000, 0x20000000, 153a8e1175bSopenharmony_ci 0x20004000, 0x00000010, 0x20400010, 0x00404000, 154a8e1175bSopenharmony_ci 0x20404010, 0x00400000, 0x00004010, 0x20000010, 155a8e1175bSopenharmony_ci 0x00400000, 0x20004000, 0x20000000, 0x00004010, 156a8e1175bSopenharmony_ci 0x20000010, 0x20404010, 0x00404000, 0x20400000, 157a8e1175bSopenharmony_ci 0x00404010, 0x20404000, 0x00000000, 0x20400010, 158a8e1175bSopenharmony_ci 0x00000010, 0x00004000, 0x20400000, 0x00404010, 159a8e1175bSopenharmony_ci 0x00004000, 0x00400010, 0x20004010, 0x00000000, 160a8e1175bSopenharmony_ci 0x20404000, 0x20000000, 0x00400010, 0x20004010 161a8e1175bSopenharmony_ci}; 162a8e1175bSopenharmony_ci 163a8e1175bSopenharmony_cistatic const uint32_t SB7[64] = 164a8e1175bSopenharmony_ci{ 165a8e1175bSopenharmony_ci 0x00200000, 0x04200002, 0x04000802, 0x00000000, 166a8e1175bSopenharmony_ci 0x00000800, 0x04000802, 0x00200802, 0x04200800, 167a8e1175bSopenharmony_ci 0x04200802, 0x00200000, 0x00000000, 0x04000002, 168a8e1175bSopenharmony_ci 0x00000002, 0x04000000, 0x04200002, 0x00000802, 169a8e1175bSopenharmony_ci 0x04000800, 0x00200802, 0x00200002, 0x04000800, 170a8e1175bSopenharmony_ci 0x04000002, 0x04200000, 0x04200800, 0x00200002, 171a8e1175bSopenharmony_ci 0x04200000, 0x00000800, 0x00000802, 0x04200802, 172a8e1175bSopenharmony_ci 0x00200800, 0x00000002, 0x04000000, 0x00200800, 173a8e1175bSopenharmony_ci 0x04000000, 0x00200800, 0x00200000, 0x04000802, 174a8e1175bSopenharmony_ci 0x04000802, 0x04200002, 0x04200002, 0x00000002, 175a8e1175bSopenharmony_ci 0x00200002, 0x04000000, 0x04000800, 0x00200000, 176a8e1175bSopenharmony_ci 0x04200800, 0x00000802, 0x00200802, 0x04200800, 177a8e1175bSopenharmony_ci 0x00000802, 0x04000002, 0x04200802, 0x04200000, 178a8e1175bSopenharmony_ci 0x00200800, 0x00000000, 0x00000002, 0x04200802, 179a8e1175bSopenharmony_ci 0x00000000, 0x00200802, 0x04200000, 0x00000800, 180a8e1175bSopenharmony_ci 0x04000002, 0x04000800, 0x00000800, 0x00200002 181a8e1175bSopenharmony_ci}; 182a8e1175bSopenharmony_ci 183a8e1175bSopenharmony_cistatic const uint32_t SB8[64] = 184a8e1175bSopenharmony_ci{ 185a8e1175bSopenharmony_ci 0x10001040, 0x00001000, 0x00040000, 0x10041040, 186a8e1175bSopenharmony_ci 0x10000000, 0x10001040, 0x00000040, 0x10000000, 187a8e1175bSopenharmony_ci 0x00040040, 0x10040000, 0x10041040, 0x00041000, 188a8e1175bSopenharmony_ci 0x10041000, 0x00041040, 0x00001000, 0x00000040, 189a8e1175bSopenharmony_ci 0x10040000, 0x10000040, 0x10001000, 0x00001040, 190a8e1175bSopenharmony_ci 0x00041000, 0x00040040, 0x10040040, 0x10041000, 191a8e1175bSopenharmony_ci 0x00001040, 0x00000000, 0x00000000, 0x10040040, 192a8e1175bSopenharmony_ci 0x10000040, 0x10001000, 0x00041040, 0x00040000, 193a8e1175bSopenharmony_ci 0x00041040, 0x00040000, 0x10041000, 0x00001000, 194a8e1175bSopenharmony_ci 0x00000040, 0x10040040, 0x00001000, 0x00041040, 195a8e1175bSopenharmony_ci 0x10001000, 0x00000040, 0x10000040, 0x10040000, 196a8e1175bSopenharmony_ci 0x10040040, 0x10000000, 0x00040000, 0x10001040, 197a8e1175bSopenharmony_ci 0x00000000, 0x10041040, 0x00040040, 0x10000040, 198a8e1175bSopenharmony_ci 0x10040000, 0x10001000, 0x10001040, 0x00000000, 199a8e1175bSopenharmony_ci 0x10041040, 0x00041000, 0x00041000, 0x00001040, 200a8e1175bSopenharmony_ci 0x00001040, 0x00040040, 0x10000000, 0x10041000 201a8e1175bSopenharmony_ci}; 202a8e1175bSopenharmony_ci 203a8e1175bSopenharmony_ci/* 204a8e1175bSopenharmony_ci * PC1: left and right halves bit-swap 205a8e1175bSopenharmony_ci */ 206a8e1175bSopenharmony_cistatic const uint32_t LHs[16] = 207a8e1175bSopenharmony_ci{ 208a8e1175bSopenharmony_ci 0x00000000, 0x00000001, 0x00000100, 0x00000101, 209a8e1175bSopenharmony_ci 0x00010000, 0x00010001, 0x00010100, 0x00010101, 210a8e1175bSopenharmony_ci 0x01000000, 0x01000001, 0x01000100, 0x01000101, 211a8e1175bSopenharmony_ci 0x01010000, 0x01010001, 0x01010100, 0x01010101 212a8e1175bSopenharmony_ci}; 213a8e1175bSopenharmony_ci 214a8e1175bSopenharmony_cistatic const uint32_t RHs[16] = 215a8e1175bSopenharmony_ci{ 216a8e1175bSopenharmony_ci 0x00000000, 0x01000000, 0x00010000, 0x01010000, 217a8e1175bSopenharmony_ci 0x00000100, 0x01000100, 0x00010100, 0x01010100, 218a8e1175bSopenharmony_ci 0x00000001, 0x01000001, 0x00010001, 0x01010001, 219a8e1175bSopenharmony_ci 0x00000101, 0x01000101, 0x00010101, 0x01010101, 220a8e1175bSopenharmony_ci}; 221a8e1175bSopenharmony_ci 222a8e1175bSopenharmony_ci/* 223a8e1175bSopenharmony_ci * Initial Permutation macro 224a8e1175bSopenharmony_ci */ 225a8e1175bSopenharmony_ci#define DES_IP(X, Y) \ 226a8e1175bSopenharmony_ci do \ 227a8e1175bSopenharmony_ci { \ 228a8e1175bSopenharmony_ci T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ 229a8e1175bSopenharmony_ci T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ 230a8e1175bSopenharmony_ci T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ 231a8e1175bSopenharmony_ci T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ 232a8e1175bSopenharmony_ci (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \ 233a8e1175bSopenharmony_ci T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \ 234a8e1175bSopenharmony_ci (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \ 235a8e1175bSopenharmony_ci } while (0) 236a8e1175bSopenharmony_ci 237a8e1175bSopenharmony_ci/* 238a8e1175bSopenharmony_ci * Final Permutation macro 239a8e1175bSopenharmony_ci */ 240a8e1175bSopenharmony_ci#define DES_FP(X, Y) \ 241a8e1175bSopenharmony_ci do \ 242a8e1175bSopenharmony_ci { \ 243a8e1175bSopenharmony_ci (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \ 244a8e1175bSopenharmony_ci T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \ 245a8e1175bSopenharmony_ci (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \ 246a8e1175bSopenharmony_ci T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ 247a8e1175bSopenharmony_ci T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ 248a8e1175bSopenharmony_ci T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ 249a8e1175bSopenharmony_ci T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ 250a8e1175bSopenharmony_ci } while (0) 251a8e1175bSopenharmony_ci 252a8e1175bSopenharmony_ci/* 253a8e1175bSopenharmony_ci * DES round macro 254a8e1175bSopenharmony_ci */ 255a8e1175bSopenharmony_ci#define DES_ROUND(X, Y) \ 256a8e1175bSopenharmony_ci do \ 257a8e1175bSopenharmony_ci { \ 258a8e1175bSopenharmony_ci T = *SK++ ^ (X); \ 259a8e1175bSopenharmony_ci (Y) ^= SB8[(T) & 0x3F] ^ \ 260a8e1175bSopenharmony_ci SB6[(T >> 8) & 0x3F] ^ \ 261a8e1175bSopenharmony_ci SB4[(T >> 16) & 0x3F] ^ \ 262a8e1175bSopenharmony_ci SB2[(T >> 24) & 0x3F]; \ 263a8e1175bSopenharmony_ci \ 264a8e1175bSopenharmony_ci T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \ 265a8e1175bSopenharmony_ci (Y) ^= SB7[(T) & 0x3F] ^ \ 266a8e1175bSopenharmony_ci SB5[(T >> 8) & 0x3F] ^ \ 267a8e1175bSopenharmony_ci SB3[(T >> 16) & 0x3F] ^ \ 268a8e1175bSopenharmony_ci SB1[(T >> 24) & 0x3F]; \ 269a8e1175bSopenharmony_ci } while (0) 270a8e1175bSopenharmony_ci 271a8e1175bSopenharmony_ci#define SWAP(a, b) \ 272a8e1175bSopenharmony_ci do \ 273a8e1175bSopenharmony_ci { \ 274a8e1175bSopenharmony_ci uint32_t t = (a); (a) = (b); (b) = t; t = 0; \ 275a8e1175bSopenharmony_ci } while (0) 276a8e1175bSopenharmony_ci 277a8e1175bSopenharmony_civoid mbedtls_des_init(mbedtls_des_context *ctx) 278a8e1175bSopenharmony_ci{ 279a8e1175bSopenharmony_ci memset(ctx, 0, sizeof(mbedtls_des_context)); 280a8e1175bSopenharmony_ci} 281a8e1175bSopenharmony_ci 282a8e1175bSopenharmony_civoid mbedtls_des_free(mbedtls_des_context *ctx) 283a8e1175bSopenharmony_ci{ 284a8e1175bSopenharmony_ci if (ctx == NULL) { 285a8e1175bSopenharmony_ci return; 286a8e1175bSopenharmony_ci } 287a8e1175bSopenharmony_ci 288a8e1175bSopenharmony_ci mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context)); 289a8e1175bSopenharmony_ci} 290a8e1175bSopenharmony_ci 291a8e1175bSopenharmony_civoid mbedtls_des3_init(mbedtls_des3_context *ctx) 292a8e1175bSopenharmony_ci{ 293a8e1175bSopenharmony_ci memset(ctx, 0, sizeof(mbedtls_des3_context)); 294a8e1175bSopenharmony_ci} 295a8e1175bSopenharmony_ci 296a8e1175bSopenharmony_civoid mbedtls_des3_free(mbedtls_des3_context *ctx) 297a8e1175bSopenharmony_ci{ 298a8e1175bSopenharmony_ci if (ctx == NULL) { 299a8e1175bSopenharmony_ci return; 300a8e1175bSopenharmony_ci } 301a8e1175bSopenharmony_ci 302a8e1175bSopenharmony_ci mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des3_context)); 303a8e1175bSopenharmony_ci} 304a8e1175bSopenharmony_ci 305a8e1175bSopenharmony_cistatic const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, 306a8e1175bSopenharmony_ci 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 307a8e1175bSopenharmony_ci 35, 37, 38, 41, 42, 44, 308a8e1175bSopenharmony_ci 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 309a8e1175bSopenharmony_ci 70, 73, 74, 76, 79, 81, 310a8e1175bSopenharmony_ci 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 311a8e1175bSopenharmony_ci 104, 107, 109, 110, 112, 312a8e1175bSopenharmony_ci 115, 117, 118, 121, 122, 124, 127, 128, 131, 313a8e1175bSopenharmony_ci 133, 134, 137, 138, 140, 314a8e1175bSopenharmony_ci 143, 145, 146, 148, 151, 152, 155, 157, 158, 315a8e1175bSopenharmony_ci 161, 162, 164, 167, 168, 316a8e1175bSopenharmony_ci 171, 173, 174, 176, 179, 181, 182, 185, 186, 317a8e1175bSopenharmony_ci 188, 191, 193, 194, 196, 318a8e1175bSopenharmony_ci 199, 200, 203, 205, 206, 208, 211, 213, 214, 319a8e1175bSopenharmony_ci 217, 218, 220, 223, 224, 320a8e1175bSopenharmony_ci 227, 229, 230, 233, 234, 236, 239, 241, 242, 321a8e1175bSopenharmony_ci 244, 247, 248, 251, 253, 322a8e1175bSopenharmony_ci 254 }; 323a8e1175bSopenharmony_ci 324a8e1175bSopenharmony_civoid mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]) 325a8e1175bSopenharmony_ci{ 326a8e1175bSopenharmony_ci int i; 327a8e1175bSopenharmony_ci 328a8e1175bSopenharmony_ci for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) { 329a8e1175bSopenharmony_ci key[i] = odd_parity_table[key[i] / 2]; 330a8e1175bSopenharmony_ci } 331a8e1175bSopenharmony_ci} 332a8e1175bSopenharmony_ci 333a8e1175bSopenharmony_ci/* 334a8e1175bSopenharmony_ci * Check the given key's parity, returns 1 on failure, 0 on SUCCESS 335a8e1175bSopenharmony_ci */ 336a8e1175bSopenharmony_ciint mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE]) 337a8e1175bSopenharmony_ci{ 338a8e1175bSopenharmony_ci int i; 339a8e1175bSopenharmony_ci 340a8e1175bSopenharmony_ci for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) { 341a8e1175bSopenharmony_ci if (key[i] != odd_parity_table[key[i] / 2]) { 342a8e1175bSopenharmony_ci return 1; 343a8e1175bSopenharmony_ci } 344a8e1175bSopenharmony_ci } 345a8e1175bSopenharmony_ci 346a8e1175bSopenharmony_ci return 0; 347a8e1175bSopenharmony_ci} 348a8e1175bSopenharmony_ci 349a8e1175bSopenharmony_ci/* 350a8e1175bSopenharmony_ci * Table of weak and semi-weak keys 351a8e1175bSopenharmony_ci * 352a8e1175bSopenharmony_ci * Source: http://en.wikipedia.org/wiki/Weak_key 353a8e1175bSopenharmony_ci * 354a8e1175bSopenharmony_ci * Weak: 355a8e1175bSopenharmony_ci * Alternating ones + zeros (0x0101010101010101) 356a8e1175bSopenharmony_ci * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) 357a8e1175bSopenharmony_ci * '0xE0E0E0E0F1F1F1F1' 358a8e1175bSopenharmony_ci * '0x1F1F1F1F0E0E0E0E' 359a8e1175bSopenharmony_ci * 360a8e1175bSopenharmony_ci * Semi-weak: 361a8e1175bSopenharmony_ci * 0x011F011F010E010E and 0x1F011F010E010E01 362a8e1175bSopenharmony_ci * 0x01E001E001F101F1 and 0xE001E001F101F101 363a8e1175bSopenharmony_ci * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 364a8e1175bSopenharmony_ci * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E 365a8e1175bSopenharmony_ci * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E 366a8e1175bSopenharmony_ci * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 367a8e1175bSopenharmony_ci * 368a8e1175bSopenharmony_ci */ 369a8e1175bSopenharmony_ci 370a8e1175bSopenharmony_ci#define WEAK_KEY_COUNT 16 371a8e1175bSopenharmony_ci 372a8e1175bSopenharmony_cistatic const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = 373a8e1175bSopenharmony_ci{ 374a8e1175bSopenharmony_ci { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, 375a8e1175bSopenharmony_ci { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, 376a8e1175bSopenharmony_ci { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, 377a8e1175bSopenharmony_ci { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, 378a8e1175bSopenharmony_ci 379a8e1175bSopenharmony_ci { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, 380a8e1175bSopenharmony_ci { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, 381a8e1175bSopenharmony_ci { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, 382a8e1175bSopenharmony_ci { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, 383a8e1175bSopenharmony_ci { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, 384a8e1175bSopenharmony_ci { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, 385a8e1175bSopenharmony_ci { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, 386a8e1175bSopenharmony_ci { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, 387a8e1175bSopenharmony_ci { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, 388a8e1175bSopenharmony_ci { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, 389a8e1175bSopenharmony_ci { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, 390a8e1175bSopenharmony_ci { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } 391a8e1175bSopenharmony_ci}; 392a8e1175bSopenharmony_ci 393a8e1175bSopenharmony_ciint mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]) 394a8e1175bSopenharmony_ci{ 395a8e1175bSopenharmony_ci int i; 396a8e1175bSopenharmony_ci 397a8e1175bSopenharmony_ci for (i = 0; i < WEAK_KEY_COUNT; i++) { 398a8e1175bSopenharmony_ci if (memcmp(weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0) { 399a8e1175bSopenharmony_ci return 1; 400a8e1175bSopenharmony_ci } 401a8e1175bSopenharmony_ci } 402a8e1175bSopenharmony_ci 403a8e1175bSopenharmony_ci return 0; 404a8e1175bSopenharmony_ci} 405a8e1175bSopenharmony_ci 406a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DES_SETKEY_ALT) 407a8e1175bSopenharmony_civoid mbedtls_des_setkey(uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE]) 408a8e1175bSopenharmony_ci{ 409a8e1175bSopenharmony_ci int i; 410a8e1175bSopenharmony_ci uint32_t X, Y, T; 411a8e1175bSopenharmony_ci 412a8e1175bSopenharmony_ci X = MBEDTLS_GET_UINT32_BE(key, 0); 413a8e1175bSopenharmony_ci Y = MBEDTLS_GET_UINT32_BE(key, 4); 414a8e1175bSopenharmony_ci 415a8e1175bSopenharmony_ci /* 416a8e1175bSopenharmony_ci * Permuted Choice 1 417a8e1175bSopenharmony_ci */ 418a8e1175bSopenharmony_ci T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); 419a8e1175bSopenharmony_ci T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T); 420a8e1175bSopenharmony_ci 421a8e1175bSopenharmony_ci X = (LHs[(X) & 0xF] << 3) | (LHs[(X >> 8) & 0xF] << 2) 422a8e1175bSopenharmony_ci | (LHs[(X >> 16) & 0xF] << 1) | (LHs[(X >> 24) & 0xF]) 423a8e1175bSopenharmony_ci | (LHs[(X >> 5) & 0xF] << 7) | (LHs[(X >> 13) & 0xF] << 6) 424a8e1175bSopenharmony_ci | (LHs[(X >> 21) & 0xF] << 5) | (LHs[(X >> 29) & 0xF] << 4); 425a8e1175bSopenharmony_ci 426a8e1175bSopenharmony_ci Y = (RHs[(Y >> 1) & 0xF] << 3) | (RHs[(Y >> 9) & 0xF] << 2) 427a8e1175bSopenharmony_ci | (RHs[(Y >> 17) & 0xF] << 1) | (RHs[(Y >> 25) & 0xF]) 428a8e1175bSopenharmony_ci | (RHs[(Y >> 4) & 0xF] << 7) | (RHs[(Y >> 12) & 0xF] << 6) 429a8e1175bSopenharmony_ci | (RHs[(Y >> 20) & 0xF] << 5) | (RHs[(Y >> 28) & 0xF] << 4); 430a8e1175bSopenharmony_ci 431a8e1175bSopenharmony_ci X &= 0x0FFFFFFF; 432a8e1175bSopenharmony_ci Y &= 0x0FFFFFFF; 433a8e1175bSopenharmony_ci 434a8e1175bSopenharmony_ci /* 435a8e1175bSopenharmony_ci * calculate subkeys 436a8e1175bSopenharmony_ci */ 437a8e1175bSopenharmony_ci for (i = 0; i < 16; i++) { 438a8e1175bSopenharmony_ci if (i < 2 || i == 8 || i == 15) { 439a8e1175bSopenharmony_ci X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; 440a8e1175bSopenharmony_ci Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; 441a8e1175bSopenharmony_ci } else { 442a8e1175bSopenharmony_ci X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; 443a8e1175bSopenharmony_ci Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; 444a8e1175bSopenharmony_ci } 445a8e1175bSopenharmony_ci 446a8e1175bSopenharmony_ci *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) 447a8e1175bSopenharmony_ci | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) 448a8e1175bSopenharmony_ci | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) 449a8e1175bSopenharmony_ci | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) 450a8e1175bSopenharmony_ci | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) 451a8e1175bSopenharmony_ci | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) 452a8e1175bSopenharmony_ci | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) 453a8e1175bSopenharmony_ci | ((Y >> 14) & 0x00000200) | ((Y) & 0x00000100) 454a8e1175bSopenharmony_ci | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) 455a8e1175bSopenharmony_ci | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) 456a8e1175bSopenharmony_ci | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); 457a8e1175bSopenharmony_ci 458a8e1175bSopenharmony_ci *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) 459a8e1175bSopenharmony_ci | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) 460a8e1175bSopenharmony_ci | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) 461a8e1175bSopenharmony_ci | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) 462a8e1175bSopenharmony_ci | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) 463a8e1175bSopenharmony_ci | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) 464a8e1175bSopenharmony_ci | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) 465a8e1175bSopenharmony_ci | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) 466a8e1175bSopenharmony_ci | ((Y) & 0x00000200) | ((Y << 7) & 0x00000100) 467a8e1175bSopenharmony_ci | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) 468a8e1175bSopenharmony_ci | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); 469a8e1175bSopenharmony_ci } 470a8e1175bSopenharmony_ci} 471a8e1175bSopenharmony_ci#endif /* !MBEDTLS_DES_SETKEY_ALT */ 472a8e1175bSopenharmony_ci 473a8e1175bSopenharmony_ci/* 474a8e1175bSopenharmony_ci * DES key schedule (56-bit, encryption) 475a8e1175bSopenharmony_ci */ 476a8e1175bSopenharmony_ciint mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]) 477a8e1175bSopenharmony_ci{ 478a8e1175bSopenharmony_ci mbedtls_des_setkey(ctx->sk, key); 479a8e1175bSopenharmony_ci 480a8e1175bSopenharmony_ci return 0; 481a8e1175bSopenharmony_ci} 482a8e1175bSopenharmony_ci 483a8e1175bSopenharmony_ci/* 484a8e1175bSopenharmony_ci * DES key schedule (56-bit, decryption) 485a8e1175bSopenharmony_ci */ 486a8e1175bSopenharmony_ciint mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]) 487a8e1175bSopenharmony_ci{ 488a8e1175bSopenharmony_ci int i; 489a8e1175bSopenharmony_ci 490a8e1175bSopenharmony_ci mbedtls_des_setkey(ctx->sk, key); 491a8e1175bSopenharmony_ci 492a8e1175bSopenharmony_ci for (i = 0; i < 16; i += 2) { 493a8e1175bSopenharmony_ci SWAP(ctx->sk[i], ctx->sk[30 - i]); 494a8e1175bSopenharmony_ci SWAP(ctx->sk[i + 1], ctx->sk[31 - i]); 495a8e1175bSopenharmony_ci } 496a8e1175bSopenharmony_ci 497a8e1175bSopenharmony_ci return 0; 498a8e1175bSopenharmony_ci} 499a8e1175bSopenharmony_ci 500a8e1175bSopenharmony_cistatic void des3_set2key(uint32_t esk[96], 501a8e1175bSopenharmony_ci uint32_t dsk[96], 502a8e1175bSopenharmony_ci const unsigned char key[MBEDTLS_DES_KEY_SIZE*2]) 503a8e1175bSopenharmony_ci{ 504a8e1175bSopenharmony_ci int i; 505a8e1175bSopenharmony_ci 506a8e1175bSopenharmony_ci mbedtls_des_setkey(esk, key); 507a8e1175bSopenharmony_ci mbedtls_des_setkey(dsk + 32, key + 8); 508a8e1175bSopenharmony_ci 509a8e1175bSopenharmony_ci for (i = 0; i < 32; i += 2) { 510a8e1175bSopenharmony_ci dsk[i] = esk[30 - i]; 511a8e1175bSopenharmony_ci dsk[i + 1] = esk[31 - i]; 512a8e1175bSopenharmony_ci 513a8e1175bSopenharmony_ci esk[i + 32] = dsk[62 - i]; 514a8e1175bSopenharmony_ci esk[i + 33] = dsk[63 - i]; 515a8e1175bSopenharmony_ci 516a8e1175bSopenharmony_ci esk[i + 64] = esk[i]; 517a8e1175bSopenharmony_ci esk[i + 65] = esk[i + 1]; 518a8e1175bSopenharmony_ci 519a8e1175bSopenharmony_ci dsk[i + 64] = dsk[i]; 520a8e1175bSopenharmony_ci dsk[i + 65] = dsk[i + 1]; 521a8e1175bSopenharmony_ci } 522a8e1175bSopenharmony_ci} 523a8e1175bSopenharmony_ci 524a8e1175bSopenharmony_ci/* 525a8e1175bSopenharmony_ci * Triple-DES key schedule (112-bit, encryption) 526a8e1175bSopenharmony_ci */ 527a8e1175bSopenharmony_ciint mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx, 528a8e1175bSopenharmony_ci const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]) 529a8e1175bSopenharmony_ci{ 530a8e1175bSopenharmony_ci uint32_t sk[96]; 531a8e1175bSopenharmony_ci 532a8e1175bSopenharmony_ci des3_set2key(ctx->sk, sk, key); 533a8e1175bSopenharmony_ci mbedtls_platform_zeroize(sk, sizeof(sk)); 534a8e1175bSopenharmony_ci 535a8e1175bSopenharmony_ci return 0; 536a8e1175bSopenharmony_ci} 537a8e1175bSopenharmony_ci 538a8e1175bSopenharmony_ci/* 539a8e1175bSopenharmony_ci * Triple-DES key schedule (112-bit, decryption) 540a8e1175bSopenharmony_ci */ 541a8e1175bSopenharmony_ciint mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx, 542a8e1175bSopenharmony_ci const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]) 543a8e1175bSopenharmony_ci{ 544a8e1175bSopenharmony_ci uint32_t sk[96]; 545a8e1175bSopenharmony_ci 546a8e1175bSopenharmony_ci des3_set2key(sk, ctx->sk, key); 547a8e1175bSopenharmony_ci mbedtls_platform_zeroize(sk, sizeof(sk)); 548a8e1175bSopenharmony_ci 549a8e1175bSopenharmony_ci return 0; 550a8e1175bSopenharmony_ci} 551a8e1175bSopenharmony_ci 552a8e1175bSopenharmony_cistatic void des3_set3key(uint32_t esk[96], 553a8e1175bSopenharmony_ci uint32_t dsk[96], 554a8e1175bSopenharmony_ci const unsigned char key[24]) 555a8e1175bSopenharmony_ci{ 556a8e1175bSopenharmony_ci int i; 557a8e1175bSopenharmony_ci 558a8e1175bSopenharmony_ci mbedtls_des_setkey(esk, key); 559a8e1175bSopenharmony_ci mbedtls_des_setkey(dsk + 32, key + 8); 560a8e1175bSopenharmony_ci mbedtls_des_setkey(esk + 64, key + 16); 561a8e1175bSopenharmony_ci 562a8e1175bSopenharmony_ci for (i = 0; i < 32; i += 2) { 563a8e1175bSopenharmony_ci dsk[i] = esk[94 - i]; 564a8e1175bSopenharmony_ci dsk[i + 1] = esk[95 - i]; 565a8e1175bSopenharmony_ci 566a8e1175bSopenharmony_ci esk[i + 32] = dsk[62 - i]; 567a8e1175bSopenharmony_ci esk[i + 33] = dsk[63 - i]; 568a8e1175bSopenharmony_ci 569a8e1175bSopenharmony_ci dsk[i + 64] = esk[30 - i]; 570a8e1175bSopenharmony_ci dsk[i + 65] = esk[31 - i]; 571a8e1175bSopenharmony_ci } 572a8e1175bSopenharmony_ci} 573a8e1175bSopenharmony_ci 574a8e1175bSopenharmony_ci/* 575a8e1175bSopenharmony_ci * Triple-DES key schedule (168-bit, encryption) 576a8e1175bSopenharmony_ci */ 577a8e1175bSopenharmony_ciint mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx, 578a8e1175bSopenharmony_ci const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]) 579a8e1175bSopenharmony_ci{ 580a8e1175bSopenharmony_ci uint32_t sk[96]; 581a8e1175bSopenharmony_ci 582a8e1175bSopenharmony_ci des3_set3key(ctx->sk, sk, key); 583a8e1175bSopenharmony_ci mbedtls_platform_zeroize(sk, sizeof(sk)); 584a8e1175bSopenharmony_ci 585a8e1175bSopenharmony_ci return 0; 586a8e1175bSopenharmony_ci} 587a8e1175bSopenharmony_ci 588a8e1175bSopenharmony_ci/* 589a8e1175bSopenharmony_ci * Triple-DES key schedule (168-bit, decryption) 590a8e1175bSopenharmony_ci */ 591a8e1175bSopenharmony_ciint mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx, 592a8e1175bSopenharmony_ci const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]) 593a8e1175bSopenharmony_ci{ 594a8e1175bSopenharmony_ci uint32_t sk[96]; 595a8e1175bSopenharmony_ci 596a8e1175bSopenharmony_ci des3_set3key(sk, ctx->sk, key); 597a8e1175bSopenharmony_ci mbedtls_platform_zeroize(sk, sizeof(sk)); 598a8e1175bSopenharmony_ci 599a8e1175bSopenharmony_ci return 0; 600a8e1175bSopenharmony_ci} 601a8e1175bSopenharmony_ci 602a8e1175bSopenharmony_ci/* 603a8e1175bSopenharmony_ci * DES-ECB block encryption/decryption 604a8e1175bSopenharmony_ci */ 605a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT) 606a8e1175bSopenharmony_ciint mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, 607a8e1175bSopenharmony_ci const unsigned char input[8], 608a8e1175bSopenharmony_ci unsigned char output[8]) 609a8e1175bSopenharmony_ci{ 610a8e1175bSopenharmony_ci int i; 611a8e1175bSopenharmony_ci uint32_t X, Y, T, *SK; 612a8e1175bSopenharmony_ci 613a8e1175bSopenharmony_ci SK = ctx->sk; 614a8e1175bSopenharmony_ci 615a8e1175bSopenharmony_ci X = MBEDTLS_GET_UINT32_BE(input, 0); 616a8e1175bSopenharmony_ci Y = MBEDTLS_GET_UINT32_BE(input, 4); 617a8e1175bSopenharmony_ci 618a8e1175bSopenharmony_ci DES_IP(X, Y); 619a8e1175bSopenharmony_ci 620a8e1175bSopenharmony_ci for (i = 0; i < 8; i++) { 621a8e1175bSopenharmony_ci DES_ROUND(Y, X); 622a8e1175bSopenharmony_ci DES_ROUND(X, Y); 623a8e1175bSopenharmony_ci } 624a8e1175bSopenharmony_ci 625a8e1175bSopenharmony_ci DES_FP(Y, X); 626a8e1175bSopenharmony_ci 627a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(Y, output, 0); 628a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(X, output, 4); 629a8e1175bSopenharmony_ci 630a8e1175bSopenharmony_ci return 0; 631a8e1175bSopenharmony_ci} 632a8e1175bSopenharmony_ci#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */ 633a8e1175bSopenharmony_ci 634a8e1175bSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_CBC) 635a8e1175bSopenharmony_ci/* 636a8e1175bSopenharmony_ci * DES-CBC buffer encryption/decryption 637a8e1175bSopenharmony_ci */ 638a8e1175bSopenharmony_ciint mbedtls_des_crypt_cbc(mbedtls_des_context *ctx, 639a8e1175bSopenharmony_ci int mode, 640a8e1175bSopenharmony_ci size_t length, 641a8e1175bSopenharmony_ci unsigned char iv[8], 642a8e1175bSopenharmony_ci const unsigned char *input, 643a8e1175bSopenharmony_ci unsigned char *output) 644a8e1175bSopenharmony_ci{ 645a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 646a8e1175bSopenharmony_ci unsigned char temp[8]; 647a8e1175bSopenharmony_ci 648a8e1175bSopenharmony_ci if (length % 8) { 649a8e1175bSopenharmony_ci return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH; 650a8e1175bSopenharmony_ci } 651a8e1175bSopenharmony_ci 652a8e1175bSopenharmony_ci if (mode == MBEDTLS_DES_ENCRYPT) { 653a8e1175bSopenharmony_ci while (length > 0) { 654a8e1175bSopenharmony_ci mbedtls_xor(output, input, iv, 8); 655a8e1175bSopenharmony_ci 656a8e1175bSopenharmony_ci ret = mbedtls_des_crypt_ecb(ctx, output, output); 657a8e1175bSopenharmony_ci if (ret != 0) { 658a8e1175bSopenharmony_ci goto exit; 659a8e1175bSopenharmony_ci } 660a8e1175bSopenharmony_ci memcpy(iv, output, 8); 661a8e1175bSopenharmony_ci 662a8e1175bSopenharmony_ci input += 8; 663a8e1175bSopenharmony_ci output += 8; 664a8e1175bSopenharmony_ci length -= 8; 665a8e1175bSopenharmony_ci } 666a8e1175bSopenharmony_ci } else { /* MBEDTLS_DES_DECRYPT */ 667a8e1175bSopenharmony_ci while (length > 0) { 668a8e1175bSopenharmony_ci memcpy(temp, input, 8); 669a8e1175bSopenharmony_ci ret = mbedtls_des_crypt_ecb(ctx, input, output); 670a8e1175bSopenharmony_ci if (ret != 0) { 671a8e1175bSopenharmony_ci goto exit; 672a8e1175bSopenharmony_ci } 673a8e1175bSopenharmony_ci 674a8e1175bSopenharmony_ci mbedtls_xor(output, output, iv, 8); 675a8e1175bSopenharmony_ci 676a8e1175bSopenharmony_ci memcpy(iv, temp, 8); 677a8e1175bSopenharmony_ci 678a8e1175bSopenharmony_ci input += 8; 679a8e1175bSopenharmony_ci output += 8; 680a8e1175bSopenharmony_ci length -= 8; 681a8e1175bSopenharmony_ci } 682a8e1175bSopenharmony_ci } 683a8e1175bSopenharmony_ci ret = 0; 684a8e1175bSopenharmony_ci 685a8e1175bSopenharmony_ciexit: 686a8e1175bSopenharmony_ci return ret; 687a8e1175bSopenharmony_ci} 688a8e1175bSopenharmony_ci#endif /* MBEDTLS_CIPHER_MODE_CBC */ 689a8e1175bSopenharmony_ci 690a8e1175bSopenharmony_ci/* 691a8e1175bSopenharmony_ci * 3DES-ECB block encryption/decryption 692a8e1175bSopenharmony_ci */ 693a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT) 694a8e1175bSopenharmony_ciint mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, 695a8e1175bSopenharmony_ci const unsigned char input[8], 696a8e1175bSopenharmony_ci unsigned char output[8]) 697a8e1175bSopenharmony_ci{ 698a8e1175bSopenharmony_ci int i; 699a8e1175bSopenharmony_ci uint32_t X, Y, T, *SK; 700a8e1175bSopenharmony_ci 701a8e1175bSopenharmony_ci SK = ctx->sk; 702a8e1175bSopenharmony_ci 703a8e1175bSopenharmony_ci X = MBEDTLS_GET_UINT32_BE(input, 0); 704a8e1175bSopenharmony_ci Y = MBEDTLS_GET_UINT32_BE(input, 4); 705a8e1175bSopenharmony_ci 706a8e1175bSopenharmony_ci DES_IP(X, Y); 707a8e1175bSopenharmony_ci 708a8e1175bSopenharmony_ci for (i = 0; i < 8; i++) { 709a8e1175bSopenharmony_ci DES_ROUND(Y, X); 710a8e1175bSopenharmony_ci DES_ROUND(X, Y); 711a8e1175bSopenharmony_ci } 712a8e1175bSopenharmony_ci 713a8e1175bSopenharmony_ci for (i = 0; i < 8; i++) { 714a8e1175bSopenharmony_ci DES_ROUND(X, Y); 715a8e1175bSopenharmony_ci DES_ROUND(Y, X); 716a8e1175bSopenharmony_ci } 717a8e1175bSopenharmony_ci 718a8e1175bSopenharmony_ci for (i = 0; i < 8; i++) { 719a8e1175bSopenharmony_ci DES_ROUND(Y, X); 720a8e1175bSopenharmony_ci DES_ROUND(X, Y); 721a8e1175bSopenharmony_ci } 722a8e1175bSopenharmony_ci 723a8e1175bSopenharmony_ci DES_FP(Y, X); 724a8e1175bSopenharmony_ci 725a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(Y, output, 0); 726a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(X, output, 4); 727a8e1175bSopenharmony_ci 728a8e1175bSopenharmony_ci return 0; 729a8e1175bSopenharmony_ci} 730a8e1175bSopenharmony_ci#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */ 731a8e1175bSopenharmony_ci 732a8e1175bSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_CBC) 733a8e1175bSopenharmony_ci/* 734a8e1175bSopenharmony_ci * 3DES-CBC buffer encryption/decryption 735a8e1175bSopenharmony_ci */ 736a8e1175bSopenharmony_ciint mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx, 737a8e1175bSopenharmony_ci int mode, 738a8e1175bSopenharmony_ci size_t length, 739a8e1175bSopenharmony_ci unsigned char iv[8], 740a8e1175bSopenharmony_ci const unsigned char *input, 741a8e1175bSopenharmony_ci unsigned char *output) 742a8e1175bSopenharmony_ci{ 743a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 744a8e1175bSopenharmony_ci unsigned char temp[8]; 745a8e1175bSopenharmony_ci 746a8e1175bSopenharmony_ci if (length % 8) { 747a8e1175bSopenharmony_ci return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH; 748a8e1175bSopenharmony_ci } 749a8e1175bSopenharmony_ci 750a8e1175bSopenharmony_ci if (mode == MBEDTLS_DES_ENCRYPT) { 751a8e1175bSopenharmony_ci while (length > 0) { 752a8e1175bSopenharmony_ci mbedtls_xor(output, input, iv, 8); 753a8e1175bSopenharmony_ci 754a8e1175bSopenharmony_ci ret = mbedtls_des3_crypt_ecb(ctx, output, output); 755a8e1175bSopenharmony_ci if (ret != 0) { 756a8e1175bSopenharmony_ci goto exit; 757a8e1175bSopenharmony_ci } 758a8e1175bSopenharmony_ci memcpy(iv, output, 8); 759a8e1175bSopenharmony_ci 760a8e1175bSopenharmony_ci input += 8; 761a8e1175bSopenharmony_ci output += 8; 762a8e1175bSopenharmony_ci length -= 8; 763a8e1175bSopenharmony_ci } 764a8e1175bSopenharmony_ci } else { /* MBEDTLS_DES_DECRYPT */ 765a8e1175bSopenharmony_ci while (length > 0) { 766a8e1175bSopenharmony_ci memcpy(temp, input, 8); 767a8e1175bSopenharmony_ci ret = mbedtls_des3_crypt_ecb(ctx, input, output); 768a8e1175bSopenharmony_ci if (ret != 0) { 769a8e1175bSopenharmony_ci goto exit; 770a8e1175bSopenharmony_ci } 771a8e1175bSopenharmony_ci 772a8e1175bSopenharmony_ci mbedtls_xor(output, output, iv, 8); 773a8e1175bSopenharmony_ci 774a8e1175bSopenharmony_ci memcpy(iv, temp, 8); 775a8e1175bSopenharmony_ci 776a8e1175bSopenharmony_ci input += 8; 777a8e1175bSopenharmony_ci output += 8; 778a8e1175bSopenharmony_ci length -= 8; 779a8e1175bSopenharmony_ci } 780a8e1175bSopenharmony_ci } 781a8e1175bSopenharmony_ci ret = 0; 782a8e1175bSopenharmony_ci 783a8e1175bSopenharmony_ciexit: 784a8e1175bSopenharmony_ci return ret; 785a8e1175bSopenharmony_ci} 786a8e1175bSopenharmony_ci#endif /* MBEDTLS_CIPHER_MODE_CBC */ 787a8e1175bSopenharmony_ci 788a8e1175bSopenharmony_ci#endif /* !MBEDTLS_DES_ALT */ 789a8e1175bSopenharmony_ci 790a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST) 791a8e1175bSopenharmony_ci/* 792a8e1175bSopenharmony_ci * DES and 3DES test vectors from: 793a8e1175bSopenharmony_ci * 794a8e1175bSopenharmony_ci * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip 795a8e1175bSopenharmony_ci */ 796a8e1175bSopenharmony_cistatic const unsigned char des3_test_keys[24] = 797a8e1175bSopenharmony_ci{ 798a8e1175bSopenharmony_ci 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 799a8e1175bSopenharmony_ci 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 800a8e1175bSopenharmony_ci 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 801a8e1175bSopenharmony_ci}; 802a8e1175bSopenharmony_ci 803a8e1175bSopenharmony_cistatic const unsigned char des3_test_buf[8] = 804a8e1175bSopenharmony_ci{ 805a8e1175bSopenharmony_ci 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 806a8e1175bSopenharmony_ci}; 807a8e1175bSopenharmony_ci 808a8e1175bSopenharmony_cistatic const unsigned char des3_test_ecb_dec[3][8] = 809a8e1175bSopenharmony_ci{ 810a8e1175bSopenharmony_ci { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 }, 811a8e1175bSopenharmony_ci { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 }, 812a8e1175bSopenharmony_ci { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D } 813a8e1175bSopenharmony_ci}; 814a8e1175bSopenharmony_ci 815a8e1175bSopenharmony_cistatic const unsigned char des3_test_ecb_enc[3][8] = 816a8e1175bSopenharmony_ci{ 817a8e1175bSopenharmony_ci { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB }, 818a8e1175bSopenharmony_ci { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 }, 819a8e1175bSopenharmony_ci { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F } 820a8e1175bSopenharmony_ci}; 821a8e1175bSopenharmony_ci 822a8e1175bSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_CBC) 823a8e1175bSopenharmony_cistatic const unsigned char des3_test_iv[8] = 824a8e1175bSopenharmony_ci{ 825a8e1175bSopenharmony_ci 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 826a8e1175bSopenharmony_ci}; 827a8e1175bSopenharmony_ci 828a8e1175bSopenharmony_cistatic const unsigned char des3_test_cbc_dec[3][8] = 829a8e1175bSopenharmony_ci{ 830a8e1175bSopenharmony_ci { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A }, 831a8e1175bSopenharmony_ci { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 }, 832a8e1175bSopenharmony_ci { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF } 833a8e1175bSopenharmony_ci}; 834a8e1175bSopenharmony_ci 835a8e1175bSopenharmony_cistatic const unsigned char des3_test_cbc_enc[3][8] = 836a8e1175bSopenharmony_ci{ 837a8e1175bSopenharmony_ci { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D }, 838a8e1175bSopenharmony_ci { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 }, 839a8e1175bSopenharmony_ci { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 } 840a8e1175bSopenharmony_ci}; 841a8e1175bSopenharmony_ci#endif /* MBEDTLS_CIPHER_MODE_CBC */ 842a8e1175bSopenharmony_ci 843a8e1175bSopenharmony_ci/* 844a8e1175bSopenharmony_ci * Checkup routine 845a8e1175bSopenharmony_ci */ 846a8e1175bSopenharmony_ciint mbedtls_des_self_test(int verbose) 847a8e1175bSopenharmony_ci{ 848a8e1175bSopenharmony_ci int i, j, u, v, ret = 0; 849a8e1175bSopenharmony_ci mbedtls_des_context ctx; 850a8e1175bSopenharmony_ci mbedtls_des3_context ctx3; 851a8e1175bSopenharmony_ci unsigned char buf[8]; 852a8e1175bSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_CBC) 853a8e1175bSopenharmony_ci unsigned char prv[8]; 854a8e1175bSopenharmony_ci unsigned char iv[8]; 855a8e1175bSopenharmony_ci#endif 856a8e1175bSopenharmony_ci 857a8e1175bSopenharmony_ci mbedtls_des_init(&ctx); 858a8e1175bSopenharmony_ci mbedtls_des3_init(&ctx3); 859a8e1175bSopenharmony_ci /* 860a8e1175bSopenharmony_ci * ECB mode 861a8e1175bSopenharmony_ci */ 862a8e1175bSopenharmony_ci for (i = 0; i < 6; i++) { 863a8e1175bSopenharmony_ci u = i >> 1; 864a8e1175bSopenharmony_ci v = i & 1; 865a8e1175bSopenharmony_ci 866a8e1175bSopenharmony_ci if (verbose != 0) { 867a8e1175bSopenharmony_ci mbedtls_printf(" DES%c-ECB-%3d (%s): ", 868a8e1175bSopenharmony_ci (u == 0) ? ' ' : '3', 56 + u * 56, 869a8e1175bSopenharmony_ci (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc"); 870a8e1175bSopenharmony_ci } 871a8e1175bSopenharmony_ci 872a8e1175bSopenharmony_ci memcpy(buf, des3_test_buf, 8); 873a8e1175bSopenharmony_ci 874a8e1175bSopenharmony_ci switch (i) { 875a8e1175bSopenharmony_ci case 0: 876a8e1175bSopenharmony_ci ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys); 877a8e1175bSopenharmony_ci break; 878a8e1175bSopenharmony_ci 879a8e1175bSopenharmony_ci case 1: 880a8e1175bSopenharmony_ci ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys); 881a8e1175bSopenharmony_ci break; 882a8e1175bSopenharmony_ci 883a8e1175bSopenharmony_ci case 2: 884a8e1175bSopenharmony_ci ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys); 885a8e1175bSopenharmony_ci break; 886a8e1175bSopenharmony_ci 887a8e1175bSopenharmony_ci case 3: 888a8e1175bSopenharmony_ci ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys); 889a8e1175bSopenharmony_ci break; 890a8e1175bSopenharmony_ci 891a8e1175bSopenharmony_ci case 4: 892a8e1175bSopenharmony_ci ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys); 893a8e1175bSopenharmony_ci break; 894a8e1175bSopenharmony_ci 895a8e1175bSopenharmony_ci case 5: 896a8e1175bSopenharmony_ci ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys); 897a8e1175bSopenharmony_ci break; 898a8e1175bSopenharmony_ci 899a8e1175bSopenharmony_ci default: 900a8e1175bSopenharmony_ci return 1; 901a8e1175bSopenharmony_ci } 902a8e1175bSopenharmony_ci if (ret != 0) { 903a8e1175bSopenharmony_ci goto exit; 904a8e1175bSopenharmony_ci } 905a8e1175bSopenharmony_ci 906a8e1175bSopenharmony_ci for (j = 0; j < 100; j++) { 907a8e1175bSopenharmony_ci if (u == 0) { 908a8e1175bSopenharmony_ci ret = mbedtls_des_crypt_ecb(&ctx, buf, buf); 909a8e1175bSopenharmony_ci } else { 910a8e1175bSopenharmony_ci ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf); 911a8e1175bSopenharmony_ci } 912a8e1175bSopenharmony_ci if (ret != 0) { 913a8e1175bSopenharmony_ci goto exit; 914a8e1175bSopenharmony_ci } 915a8e1175bSopenharmony_ci } 916a8e1175bSopenharmony_ci 917a8e1175bSopenharmony_ci if ((v == MBEDTLS_DES_DECRYPT && 918a8e1175bSopenharmony_ci memcmp(buf, des3_test_ecb_dec[u], 8) != 0) || 919a8e1175bSopenharmony_ci (v != MBEDTLS_DES_DECRYPT && 920a8e1175bSopenharmony_ci memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) { 921a8e1175bSopenharmony_ci if (verbose != 0) { 922a8e1175bSopenharmony_ci mbedtls_printf("failed\n"); 923a8e1175bSopenharmony_ci } 924a8e1175bSopenharmony_ci 925a8e1175bSopenharmony_ci ret = 1; 926a8e1175bSopenharmony_ci goto exit; 927a8e1175bSopenharmony_ci } 928a8e1175bSopenharmony_ci 929a8e1175bSopenharmony_ci if (verbose != 0) { 930a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 931a8e1175bSopenharmony_ci } 932a8e1175bSopenharmony_ci } 933a8e1175bSopenharmony_ci 934a8e1175bSopenharmony_ci if (verbose != 0) { 935a8e1175bSopenharmony_ci mbedtls_printf("\n"); 936a8e1175bSopenharmony_ci } 937a8e1175bSopenharmony_ci 938a8e1175bSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_CBC) 939a8e1175bSopenharmony_ci /* 940a8e1175bSopenharmony_ci * CBC mode 941a8e1175bSopenharmony_ci */ 942a8e1175bSopenharmony_ci for (i = 0; i < 6; i++) { 943a8e1175bSopenharmony_ci u = i >> 1; 944a8e1175bSopenharmony_ci v = i & 1; 945a8e1175bSopenharmony_ci 946a8e1175bSopenharmony_ci if (verbose != 0) { 947a8e1175bSopenharmony_ci mbedtls_printf(" DES%c-CBC-%3d (%s): ", 948a8e1175bSopenharmony_ci (u == 0) ? ' ' : '3', 56 + u * 56, 949a8e1175bSopenharmony_ci (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc"); 950a8e1175bSopenharmony_ci } 951a8e1175bSopenharmony_ci 952a8e1175bSopenharmony_ci memcpy(iv, des3_test_iv, 8); 953a8e1175bSopenharmony_ci memcpy(prv, des3_test_iv, 8); 954a8e1175bSopenharmony_ci memcpy(buf, des3_test_buf, 8); 955a8e1175bSopenharmony_ci 956a8e1175bSopenharmony_ci switch (i) { 957a8e1175bSopenharmony_ci case 0: 958a8e1175bSopenharmony_ci ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys); 959a8e1175bSopenharmony_ci break; 960a8e1175bSopenharmony_ci 961a8e1175bSopenharmony_ci case 1: 962a8e1175bSopenharmony_ci ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys); 963a8e1175bSopenharmony_ci break; 964a8e1175bSopenharmony_ci 965a8e1175bSopenharmony_ci case 2: 966a8e1175bSopenharmony_ci ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys); 967a8e1175bSopenharmony_ci break; 968a8e1175bSopenharmony_ci 969a8e1175bSopenharmony_ci case 3: 970a8e1175bSopenharmony_ci ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys); 971a8e1175bSopenharmony_ci break; 972a8e1175bSopenharmony_ci 973a8e1175bSopenharmony_ci case 4: 974a8e1175bSopenharmony_ci ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys); 975a8e1175bSopenharmony_ci break; 976a8e1175bSopenharmony_ci 977a8e1175bSopenharmony_ci case 5: 978a8e1175bSopenharmony_ci ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys); 979a8e1175bSopenharmony_ci break; 980a8e1175bSopenharmony_ci 981a8e1175bSopenharmony_ci default: 982a8e1175bSopenharmony_ci return 1; 983a8e1175bSopenharmony_ci } 984a8e1175bSopenharmony_ci if (ret != 0) { 985a8e1175bSopenharmony_ci goto exit; 986a8e1175bSopenharmony_ci } 987a8e1175bSopenharmony_ci 988a8e1175bSopenharmony_ci if (v == MBEDTLS_DES_DECRYPT) { 989a8e1175bSopenharmony_ci for (j = 0; j < 100; j++) { 990a8e1175bSopenharmony_ci if (u == 0) { 991a8e1175bSopenharmony_ci ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf); 992a8e1175bSopenharmony_ci } else { 993a8e1175bSopenharmony_ci ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf); 994a8e1175bSopenharmony_ci } 995a8e1175bSopenharmony_ci if (ret != 0) { 996a8e1175bSopenharmony_ci goto exit; 997a8e1175bSopenharmony_ci } 998a8e1175bSopenharmony_ci } 999a8e1175bSopenharmony_ci } else { 1000a8e1175bSopenharmony_ci for (j = 0; j < 100; j++) { 1001a8e1175bSopenharmony_ci unsigned char tmp[8]; 1002a8e1175bSopenharmony_ci 1003a8e1175bSopenharmony_ci if (u == 0) { 1004a8e1175bSopenharmony_ci ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf); 1005a8e1175bSopenharmony_ci } else { 1006a8e1175bSopenharmony_ci ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf); 1007a8e1175bSopenharmony_ci } 1008a8e1175bSopenharmony_ci if (ret != 0) { 1009a8e1175bSopenharmony_ci goto exit; 1010a8e1175bSopenharmony_ci } 1011a8e1175bSopenharmony_ci 1012a8e1175bSopenharmony_ci memcpy(tmp, prv, 8); 1013a8e1175bSopenharmony_ci memcpy(prv, buf, 8); 1014a8e1175bSopenharmony_ci memcpy(buf, tmp, 8); 1015a8e1175bSopenharmony_ci } 1016a8e1175bSopenharmony_ci 1017a8e1175bSopenharmony_ci memcpy(buf, prv, 8); 1018a8e1175bSopenharmony_ci } 1019a8e1175bSopenharmony_ci 1020a8e1175bSopenharmony_ci if ((v == MBEDTLS_DES_DECRYPT && 1021a8e1175bSopenharmony_ci memcmp(buf, des3_test_cbc_dec[u], 8) != 0) || 1022a8e1175bSopenharmony_ci (v != MBEDTLS_DES_DECRYPT && 1023a8e1175bSopenharmony_ci memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) { 1024a8e1175bSopenharmony_ci if (verbose != 0) { 1025a8e1175bSopenharmony_ci mbedtls_printf("failed\n"); 1026a8e1175bSopenharmony_ci } 1027a8e1175bSopenharmony_ci 1028a8e1175bSopenharmony_ci ret = 1; 1029a8e1175bSopenharmony_ci goto exit; 1030a8e1175bSopenharmony_ci } 1031a8e1175bSopenharmony_ci 1032a8e1175bSopenharmony_ci if (verbose != 0) { 1033a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 1034a8e1175bSopenharmony_ci } 1035a8e1175bSopenharmony_ci } 1036a8e1175bSopenharmony_ci#endif /* MBEDTLS_CIPHER_MODE_CBC */ 1037a8e1175bSopenharmony_ci 1038a8e1175bSopenharmony_ci if (verbose != 0) { 1039a8e1175bSopenharmony_ci mbedtls_printf("\n"); 1040a8e1175bSopenharmony_ci } 1041a8e1175bSopenharmony_ci 1042a8e1175bSopenharmony_ciexit: 1043a8e1175bSopenharmony_ci mbedtls_des_free(&ctx); 1044a8e1175bSopenharmony_ci mbedtls_des3_free(&ctx3); 1045a8e1175bSopenharmony_ci 1046a8e1175bSopenharmony_ci if (ret != 0) { 1047a8e1175bSopenharmony_ci ret = 1; 1048a8e1175bSopenharmony_ci } 1049a8e1175bSopenharmony_ci return ret; 1050a8e1175bSopenharmony_ci} 1051a8e1175bSopenharmony_ci 1052a8e1175bSopenharmony_ci#endif /* MBEDTLS_SELF_TEST */ 1053a8e1175bSopenharmony_ci 1054a8e1175bSopenharmony_ci#endif /* MBEDTLS_DES_C */ 1055