From a0aee3064484fb566839e6d847afb38971ecf73f Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 5 Jul 2019 13:52:47 +0100 Subject: [PATCH] Remove crypto C files Remove unused cryptography C files, as these are sourced from Mbed Crypto now. --- library/aes.c | 2209 ----------------------- library/aesni.c | 470 ----- library/arc4.c | 201 --- library/aria.c | 1079 ------------ library/asn1parse.c | 389 ----- library/asn1write.c | 464 ----- library/base64.c | 293 ---- library/bignum.c | 2837 ------------------------------ library/blowfish.c | 696 -------- library/camellia.c | 1114 ------------ library/ccm.c | 552 ------ library/chacha20.c | 570 ------ library/chachapoly.c | 540 ------ library/cipher.c | 1540 ---------------- library/cipher_wrap.c | 2411 ------------------------- library/cmac.c | 1078 ------------ library/ctr_drbg.c | 751 -------- library/des.c | 1064 ------------ library/dhm.c | 712 -------- library/ecdh.c | 680 -------- library/ecdsa.c | 899 ---------- library/ecjpake.c | 1140 ------------ library/ecp.c | 3089 --------------------------------- library/ecp_curves.c | 1470 ---------------- library/entropy.c | 721 -------- library/entropy_poll.c | 236 --- library/gcm.c | 1020 ----------- library/havege.c | 241 --- library/hkdf.c | 192 -- library/hmac_drbg.c | 580 ------- library/md.c | 475 ----- library/md2.c | 363 ---- library/md4.c | 484 ------ library/md5.c | 498 ------ library/md_wrap.c | 586 ------- library/memory_buffer_alloc.c | 750 -------- library/nist_kw.c | 755 -------- library/oid.c | 772 -------- library/padlock.c | 170 -- library/pem.c | 490 ------ library/pk.c | 646 ------- library/pk_wrap.c | 1058 ----------- library/pkcs12.c | 365 ---- library/pkcs5.c | 417 ----- library/pkparse.c | 1482 ---------------- library/pkwrite.c | 606 ------- library/platform.c | 391 ----- library/platform_util.c | 136 -- library/poly1305.c | 559 ------ library/ripemd160.c | 559 ------ library/rsa.c | 2729 ----------------------------- library/rsa_internal.c | 492 ------ library/sha1.c | 573 ------ library/sha256.c | 586 ------- library/sha512.c | 636 ------- library/threading.c | 187 -- library/timing.c | 536 ------ library/xtea.c | 277 --- 58 files changed, 46816 deletions(-) delete mode 100644 library/aes.c delete mode 100644 library/aesni.c delete mode 100644 library/arc4.c delete mode 100644 library/aria.c delete mode 100644 library/asn1parse.c delete mode 100644 library/asn1write.c delete mode 100644 library/base64.c delete mode 100644 library/bignum.c delete mode 100644 library/blowfish.c delete mode 100644 library/camellia.c delete mode 100644 library/ccm.c delete mode 100644 library/chacha20.c delete mode 100644 library/chachapoly.c delete mode 100644 library/cipher.c delete mode 100644 library/cipher_wrap.c delete mode 100644 library/cmac.c delete mode 100644 library/ctr_drbg.c delete mode 100644 library/des.c delete mode 100644 library/dhm.c delete mode 100644 library/ecdh.c delete mode 100644 library/ecdsa.c delete mode 100644 library/ecjpake.c delete mode 100644 library/ecp.c delete mode 100644 library/ecp_curves.c delete mode 100644 library/entropy.c delete mode 100644 library/entropy_poll.c delete mode 100644 library/gcm.c delete mode 100644 library/havege.c delete mode 100644 library/hkdf.c delete mode 100644 library/hmac_drbg.c delete mode 100644 library/md.c delete mode 100644 library/md2.c delete mode 100644 library/md4.c delete mode 100644 library/md5.c delete mode 100644 library/md_wrap.c delete mode 100644 library/memory_buffer_alloc.c delete mode 100644 library/nist_kw.c delete mode 100644 library/oid.c delete mode 100644 library/padlock.c delete mode 100644 library/pem.c delete mode 100644 library/pk.c delete mode 100644 library/pk_wrap.c delete mode 100644 library/pkcs12.c delete mode 100644 library/pkcs5.c delete mode 100644 library/pkparse.c delete mode 100644 library/pkwrite.c delete mode 100644 library/platform.c delete mode 100644 library/platform_util.c delete mode 100644 library/poly1305.c delete mode 100644 library/ripemd160.c delete mode 100644 library/rsa.c delete mode 100644 library/rsa_internal.c delete mode 100644 library/sha1.c delete mode 100644 library/sha256.c delete mode 100644 library/sha512.c delete mode 100644 library/threading.c delete mode 100644 library/timing.c delete mode 100644 library/xtea.c diff --git a/library/aes.c b/library/aes.c deleted file mode 100644 index aff0a9939a..0000000000 --- a/library/aes.c +++ /dev/null @@ -1,2209 +0,0 @@ -/* - * FIPS-197 compliant AES implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. - * - * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf - * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_AES_C) - -#include - -#include "mbedtls/aes.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#if defined(MBEDTLS_PADLOCK_C) -#include "mbedtls/padlock.h" -#endif -#if defined(MBEDTLS_AESNI_C) -#include "mbedtls/aesni.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_AES_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define AES_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA ) -#define AES_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -#if defined(MBEDTLS_PADLOCK_C) && \ - ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) -static int aes_padlock_ace = -1; -#endif - -#if defined(MBEDTLS_AES_ROM_TABLES) -/* - * Forward S-box - */ -static const unsigned char FSb[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* - * Forward tables - */ -#define FT \ -\ - V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ - V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ - V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ - V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ - V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ - V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ - V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ - V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ - V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ - V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ - V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ - V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ - V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ - V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ - V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ - V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ - V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ - V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ - V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ - V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ - V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ - V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ - V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ - V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ - V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ - V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ - V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ - V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ - V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ - V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ - V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ - V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ - V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ - V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ - V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ - V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ - V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ - V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ - V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ - V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ - V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ - V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ - V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ - V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ - V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ - V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ - V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ - V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ - V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ - V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ - V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ - V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ - V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ - V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ - V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ - V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ - V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ - V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ - V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ - V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ - V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ - V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ - V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ - V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t FT0[256] = { FT }; -#undef V - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t FT1[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t FT2[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t FT3[256] = { FT }; -#undef V - -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -#undef FT - -/* - * Reverse S-box - */ -static const unsigned char RSb[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* - * Reverse tables - */ -#define RT \ -\ - V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ - V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ - V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ - V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ - V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ - V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ - V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ - V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ - V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ - V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ - V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ - V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ - V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ - V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ - V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ - V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ - V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ - V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ - V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ - V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ - V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ - V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ - V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ - V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ - V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ - V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ - V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ - V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ - V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ - V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ - V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ - V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ - V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ - V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ - V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ - V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ - V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ - V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ - V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ - V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ - V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ - V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ - V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ - V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ - V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ - V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ - V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ - V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ - V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ - V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ - V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ - V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ - V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ - V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ - V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ - V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ - V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ - V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ - V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ - V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ - V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ - V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ - V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ - V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t RT0[256] = { RT }; -#undef V - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t RT1[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t RT2[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t RT3[256] = { RT }; -#undef V - -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -#undef RT - -/* - * Round constants - */ -static const uint32_t RCON[10] = -{ - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x0000001B, 0x00000036 -}; - -#else /* MBEDTLS_AES_ROM_TABLES */ - -/* - * Forward S-box & tables - */ -static unsigned char FSb[256]; -static uint32_t FT0[256]; -#if !defined(MBEDTLS_AES_FEWER_TABLES) -static uint32_t FT1[256]; -static uint32_t FT2[256]; -static uint32_t FT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -/* - * Reverse S-box & tables - */ -static unsigned char RSb[256]; -static uint32_t RT0[256]; -#if !defined(MBEDTLS_AES_FEWER_TABLES) -static uint32_t RT1[256]; -static uint32_t RT2[256]; -static uint32_t RT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -/* - * Round constants - */ -static uint32_t RCON[10]; - -/* - * Tables generation code - */ -#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 ) -#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) ) -#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 ) - -static int aes_init_done = 0; - -static void aes_gen_tables( void ) -{ - int i, x, y, z; - int pow[256]; - int log[256]; - - /* - * compute pow and log tables over GF(2^8) - */ - for( i = 0, x = 1; i < 256; i++ ) - { - pow[i] = x; - log[x] = i; - x = ( x ^ XTIME( x ) ) & 0xFF; - } - - /* - * calculate the round constants - */ - for( i = 0, x = 1; i < 10; i++ ) - { - RCON[i] = (uint32_t) x; - x = XTIME( x ) & 0xFF; - } - - /* - * generate the forward and reverse S-boxes - */ - FSb[0x00] = 0x63; - RSb[0x63] = 0x00; - - for( i = 1; i < 256; i++ ) - { - x = pow[255 - log[i]]; - - y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y ^ 0x63; - - FSb[i] = (unsigned char) x; - RSb[x] = (unsigned char) i; - } - - /* - * generate the forward and reverse tables - */ - for( i = 0; i < 256; i++ ) - { - x = FSb[i]; - y = XTIME( x ) & 0xFF; - z = ( y ^ x ) & 0xFF; - - FT0[i] = ( (uint32_t) y ) ^ - ( (uint32_t) x << 8 ) ^ - ( (uint32_t) x << 16 ) ^ - ( (uint32_t) z << 24 ); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - FT1[i] = ROTL8( FT0[i] ); - FT2[i] = ROTL8( FT1[i] ); - FT3[i] = ROTL8( FT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - - x = RSb[i]; - - RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ - ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ - ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ - ( (uint32_t) MUL( 0x0B, x ) << 24 ); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - RT1[i] = ROTL8( RT0[i] ); - RT2[i] = ROTL8( RT1[i] ); - RT3[i] = ROTL8( RT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - } -} - -#undef ROTL8 - -#endif /* MBEDTLS_AES_ROM_TABLES */ - -#if defined(MBEDTLS_AES_FEWER_TABLES) - -#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) ) -#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) ) -#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) ) - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) ROTL8( RT0[idx] ) -#define AES_RT2(idx) ROTL16( RT0[idx] ) -#define AES_RT3(idx) ROTL24( RT0[idx] ) - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) ROTL8( FT0[idx] ) -#define AES_FT2(idx) ROTL16( FT0[idx] ) -#define AES_FT3(idx) ROTL24( FT0[idx] ) - -#else /* MBEDTLS_AES_FEWER_TABLES */ - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) RT1[idx] -#define AES_RT2(idx) RT2[idx] -#define AES_RT3(idx) RT3[idx] - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) FT1[idx] -#define AES_FT2(idx) FT2[idx] -#define AES_FT3(idx) FT3[idx] - -#endif /* MBEDTLS_AES_FEWER_TABLES */ - -void mbedtls_aes_init( mbedtls_aes_context *ctx ) -{ - AES_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_aes_context ) ); -} - -void mbedtls_aes_free( mbedtls_aes_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ) -{ - AES_VALIDATE( ctx != NULL ); - - mbedtls_aes_init( &ctx->crypt ); - mbedtls_aes_init( &ctx->tweak ); -} - -void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_aes_free( &ctx->crypt ); - mbedtls_aes_free( &ctx->tweak ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* - * AES key schedule (encryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) -int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - unsigned int i; - uint32_t *RK; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - switch( keybits ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - -#if !defined(MBEDTLS_AES_ROM_TABLES) - if( aes_init_done == 0 ) - { - aes_gen_tables(); - aes_init_done = 1; - } -#endif - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); -#endif - - for( i = 0; i < ( keybits >> 5 ); i++ ) - { - GET_UINT32_LE( RK[i], key, i << 2 ); - } - - switch( ctx->nr ) - { - case 10: - - for( i = 0; i < 10; i++, RK += 4 ) - { - RK[4] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 12: - - for( i = 0; i < 8; i++, RK += 6 ) - { - RK[6] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 14: - - for( i = 0; i < 7; i++, RK += 8 ) - { - RK[8] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - } - - return( 0 ); -} -#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ - -/* - * AES key schedule (decryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) -int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - int i, j, ret; - mbedtls_aes_context cty; - uint32_t *RK; - uint32_t *SK; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - mbedtls_aes_init( &cty ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - - /* Also checks keybits */ - if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) - goto exit; - - ctx->nr = cty.nr; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - { - mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, - (const unsigned char *) cty.rk, ctx->nr ); - goto exit; - } -#endif - - SK = cty.rk + cty.nr * 4; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) - { - for( j = 0; j < 4; j++, SK++ ) - { - *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^ - AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^ - AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^ - AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] ); - } - } - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - -exit: - mbedtls_aes_free( &cty ); - - return( ret ); -} - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int mbedtls_aes_xts_decode_keys( const unsigned char *key, - unsigned int keybits, - const unsigned char **key1, - unsigned int *key1bits, - const unsigned char **key2, - unsigned int *key2bits ) -{ - const unsigned int half_keybits = keybits / 2; - const unsigned int half_keybytes = half_keybits / 8; - - switch( keybits ) - { - case 256: break; - case 512: break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - - *key1bits = half_keybits; - *key2bits = half_keybits; - *key1 = &key[0]; - *key2 = &key[half_keybytes]; - - return 0; -} - -int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for the encryption mode. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for encryption. */ - return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ); -} - -int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for encryption. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for decryption. */ - return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \ - AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \ - AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \ - AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \ - AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \ - } while( 0 ) - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \ - AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \ - AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \ - AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \ - AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \ - } while( 0 ) - -/* - * AES-ECB block encryption - */ -#if !defined(MBEDTLS_AES_ENCRYPT_ALT) -int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; - - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); - - return( 0 ); -} -#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - mbedtls_internal_aes_encrypt( ctx, input, output ); -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/* - * AES-ECB block decryption - */ -#if !defined(MBEDTLS_AES_DECRYPT_ALT) -int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; - - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); - - return( 0 ); -} -#endif /* !MBEDTLS_AES_DECRYPT_ALT */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - mbedtls_internal_aes_decrypt( ctx, input, output ); -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/* - * AES-ECB block encryption/decryption - */ -int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); -#endif - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_ENCRYPT ) - return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); - else - return( mbedtls_internal_aes_decrypt( ctx, input, output ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * AES-CBC buffer encryption/decryption - */ -int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[16]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - if( length % 16 ) - return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 16 ); - mbedtls_aes_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_aes_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - -/* Endianess with 64 bits values */ -#ifndef GET_UINT64_LE -#define GET_UINT64_LE(n,b,i) \ -{ \ - (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \ - | ( (uint64_t) (b)[(i) + 6] << 48 ) \ - | ( (uint64_t) (b)[(i) + 5] << 40 ) \ - | ( (uint64_t) (b)[(i) + 4] << 32 ) \ - | ( (uint64_t) (b)[(i) + 3] << 24 ) \ - | ( (uint64_t) (b)[(i) + 2] << 16 ) \ - | ( (uint64_t) (b)[(i) + 1] << 8 ) \ - | ( (uint64_t) (b)[(i) ] ); \ -} -#endif - -#ifndef PUT_UINT64_LE -#define PUT_UINT64_LE(n,b,i) \ -{ \ - (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \ - (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \ - (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \ - (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) ] = (unsigned char) ( (n) ); \ -} -#endif - -typedef unsigned char mbedtls_be128[16]; - -/* - * GF(2^128) multiplication function - * - * This function multiplies a field element by x in the polynomial field - * representation. It uses 64-bit word operations to gain speed but compensates - * for machine endianess and hence works correctly on both big and little - * endian machines. - */ -static void mbedtls_gf128mul_x_ble( unsigned char r[16], - const unsigned char x[16] ) -{ - uint64_t a, b, ra, rb; - - GET_UINT64_LE( a, x, 0 ); - GET_UINT64_LE( b, x, 8 ); - - ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) ); - rb = ( a >> 63 ) | ( b << 1 ); - - PUT_UINT64_LE( ra, r, 0 ); - PUT_UINT64_LE( rb, r, 8 ); -} - -/* - * AES-XTS buffer encryption/decryption - */ -int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t blocks = length / 16; - size_t leftover = length % 16; - unsigned char tweak[16]; - unsigned char prev_tweak[16]; - unsigned char tmp[16]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( data_unit != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - /* Data units must be at least 16 bytes long. */ - if( length < 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ - if( length > ( 1 << 20 ) * 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* Compute the tweak. */ - ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, - data_unit, tweak ); - if( ret != 0 ) - return( ret ); - - while( blocks-- ) - { - size_t i; - - if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) - { - /* We are on the last block in a decrypt operation that has - * leftover bytes, so we need to use the next tweak for this block, - * and this tweak for the lefover bytes. Save the current tweak for - * the leftovers and then update the current tweak for use on this, - * the last full block. */ - memcpy( prev_tweak, tweak, sizeof( tweak ) ); - mbedtls_gf128mul_x_ble( tweak, tweak ); - } - - for( i = 0; i < 16; i++ ) - tmp[i] = input[i] ^ tweak[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return( ret ); - - for( i = 0; i < 16; i++ ) - output[i] = tmp[i] ^ tweak[i]; - - /* Update the tweak for the next block. */ - mbedtls_gf128mul_x_ble( tweak, tweak ); - - output += 16; - input += 16; - } - - if( leftover ) - { - /* If we are on the leftover bytes in a decrypt operation, we need to - * use the previous tweak for these bytes (as saved in prev_tweak). */ - unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; - - /* We are now on the final part of the data unit, which doesn't divide - * evenly by 16. It's time for ciphertext stealing. */ - size_t i; - unsigned char *prev_output = output - 16; - - /* Copy ciphertext bytes from the previous block to our output for each - * byte of cyphertext we won't steal. At the same time, copy the - * remainder of the input for this final round (since the loop bounds - * are the same). */ - for( i = 0; i < leftover; i++ ) - { - output[i] = prev_output[i]; - tmp[i] = input[i] ^ t[i]; - } - - /* Copy ciphertext bytes from the previous block for input in this - * round. */ - for( ; i < 16; i++ ) - tmp[i] = prev_output[i] ^ t[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return ret; - - /* Write the result back to the previous block, overriding the previous - * output we copied. */ - for( i = 0; i < 16; i++ ) - prev_output[i] = tmp[i] ^ t[i]; - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} - -/* - * AES-CFB8 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - unsigned char c; - unsigned char ov[17]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - while( length-- ) - { - memcpy( ov, iv, 16 ); - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - if( mode == MBEDTLS_AES_DECRYPT ) - ov[16] = *input; - - c = *output++ = (unsigned char)( iv[0] ^ *input++ ); - - if( mode == MBEDTLS_AES_ENCRYPT ) - ov[16] = c; - - memcpy( iv, ov + 1, 16 ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB (Output Feedback Mode) buffer encryption/decryption - */ -int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret = 0; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) - { - ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - if( ret != 0 ) - goto exit; - } - *output++ = *input++ ^ iv[n]; - - n = ( n + 1 ) & 0x0F; - } - - *iv_off = n; - -exit: - return( ret ); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR buffer encryption/decryption - */ -int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( nc_off != NULL ); - AES_VALIDATE_RET( nonce_counter != NULL ); - AES_VALIDATE_RET( stream_block != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *nc_off; - - if ( n > 0x0F ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); - - for( i = 16; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#endif /* !MBEDTLS_AES_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * AES test vectors from: - * - * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip - */ -static const unsigned char aes_test_ecb_dec[3][16] = -{ - { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, - 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, - { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, - 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, - { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, - 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } -}; - -static const unsigned char aes_test_ecb_enc[3][16] = -{ - { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, - 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, - { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, - 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, - { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, - 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const unsigned char aes_test_cbc_dec[3][16] = -{ - { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, - 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, - { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, - 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, - { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, - 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } -}; - -static const unsigned char aes_test_cbc_enc[3][16] = -{ - { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, - 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, - { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, - 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, - { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, - 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 test vectors from: - * - * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf - */ -static const unsigned char aes_test_cfb128_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_cfb128_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_cfb128_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_cfb128_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, - 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, - 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, - 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, - 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, - 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, - 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, - 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, - 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, - 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, - 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, - 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, - 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, - 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, - 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, - 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB test vectors from: - * - * https://csrc.nist.gov/publications/detail/sp/800-38a/final - */ -static const unsigned char aes_test_ofb_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_ofb_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_ofb_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_ofb_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, - 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, - 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, - 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, - 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, - 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, - 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, - 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, - 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, - 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, - 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, - 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, - 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, - 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, - 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, - 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc3686.html - */ - -static const unsigned char aes_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char aes_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char aes_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char aes_test_ctr_ct[3][48] = -{ - { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, - 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, - { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, - 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, - 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, - 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, - { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, - 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, - 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, - 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, - 0x25, 0xB2, 0x07, 0x2F } -}; - -static const int aes_test_ctr_len[3] = - { 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/* - * AES-XTS test vectors from: - * - * IEEE P1619/D16 Annex B - * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf - * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) - */ -static const unsigned char aes_test_xts_key[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, - { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, -}; - -static const unsigned char aes_test_xts_pt32[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, -}; - -static const unsigned char aes_test_xts_ct32[][32] = -{ - { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, - 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, - 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, - 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, - { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, - 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, - 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, - 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, - { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, - 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, - 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, - 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, -}; - -static const unsigned char aes_test_xts_data_unit[][16] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -}; - -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* - * Checkup routine - */ -int mbedtls_aes_self_test( int verbose ) -{ - int ret = 0, i, j, u, mode; - unsigned int keybits; - unsigned char key[32]; - unsigned char buf[64]; - const unsigned char *aes_tests; -#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_OFB) - size_t offset; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) - int len; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - mbedtls_aes_context ctx; - - memset( key, 0, 32 ); - mbedtls_aes_init( &ctx ); - - /* - * ECB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-ECB-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( buf, 0, 16 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); - aes_tests = aes_test_ecb_dec[u]; - } - else - { - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - aes_tests = aes_test_ecb_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - for( j = 0; j < 10000; j++ ) - { - ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf ); - if( ret != 0 ) - goto exit; - } - - if( memcmp( buf, aes_tests, 16 ) != 0 ) - { - 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; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CBC-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( iv , 0, 16 ); - memset( prv, 0, 16 ); - memset( buf, 0, 16 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); - aes_tests = aes_test_cbc_dec[u]; - } - else - { - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - aes_tests = aes_test_cbc_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - for( j = 0; j < 10000; j++ ) - { - if( mode == MBEDTLS_AES_ENCRYPT ) - { - unsigned char tmp[16]; - - memcpy( tmp, prv, 16 ); - memcpy( prv, buf, 16 ); - memcpy( buf, tmp, 16 ); - } - - ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - } - - if( memcmp( buf, aes_tests, 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /* - * CFB128 mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_cfb128_iv, 16 ); - memcpy( key, aes_test_cfb128_key[u], keybits / 8 ); - - offset = 0; - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_cfb128_ct[u], 64 ); - aes_tests = aes_test_cfb128_pt; - } - else - { - memcpy( buf, aes_test_cfb128_pt, 64 ); - aes_tests = aes_test_cfb128_ct[u]; - } - - ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, 64 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /* - * OFB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-OFB-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_ofb_iv, 16 ); - memcpy( key, aes_test_ofb_key[u], keybits / 8 ); - - offset = 0; - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_ofb_ct[u], 64 ); - aes_tests = aes_test_ofb_pt; - } - else - { - memcpy( buf, aes_test_ofb_pt, 64 ); - aes_tests = aes_test_ofb_ct[u]; - } - - ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, 64 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CTR-128 (%s): ", - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); - memcpy( key, aes_test_ctr_key[u], 16 ); - - offset = 0; - if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 ) - goto exit; - - len = aes_test_ctr_len[u]; - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_ctr_ct[u], len ); - aes_tests = aes_test_ctr_pt[u]; - } - else - { - memcpy( buf, aes_test_ctr_pt[u], len ); - aes_tests = aes_test_ctr_ct[u]; - } - - ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, - stream_block, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, len ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { - static const int num_tests = - sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); - mbedtls_aes_xts_context ctx_xts; - - /* - * XTS mode - */ - mbedtls_aes_xts_init( &ctx_xts ); - - for( i = 0; i < num_tests << 1; i++ ) - { - const unsigned char *data_unit; - u = i >> 1; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-XTS-128 (%s): ", - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( key, 0, sizeof( key ) ); - memcpy( key, aes_test_xts_key[u], 32 ); - data_unit = aes_test_xts_data_unit[u]; - - len = sizeof( *aes_test_xts_ct32 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_ct32[u], len ); - aes_tests = aes_test_xts_pt32[u]; - } - else - { - ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_pt32[u], len ); - aes_tests = aes_test_xts_ct32[u]; - } - - - ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit, - buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, len ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - mbedtls_aes_xts_free( &ctx_xts ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - - ret = 0; - -exit: - if( ret != 0 && verbose != 0 ) - mbedtls_printf( "failed\n" ); - - mbedtls_aes_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_AES_C */ diff --git a/library/aesni.c b/library/aesni.c deleted file mode 100644 index 062708b047..0000000000 --- a/library/aesni.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * AES-NI support functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set - * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/ - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_AESNI_C) - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) -#warning "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code." -#endif -#endif - -#include "mbedtls/aesni.h" - -#include - -#ifndef asm -#define asm __asm -#endif - -#if defined(MBEDTLS_HAVE_X86_64) - -/* - * AES-NI support detection routine - */ -int mbedtls_aesni_has_support( unsigned int what ) -{ - static int done = 0; - static unsigned int c = 0; - - if( ! done ) - { - asm( "movl $1, %%eax \n\t" - "cpuid \n\t" - : "=c" (c) - : - : "eax", "ebx", "edx" ); - done = 1; - } - - return( ( c & what ) != 0 ); -} - -/* - * Binutils needs to be at least 2.19 to support AES-NI instructions. - * Unfortunately, a lot of users have a lower version now (2014-04). - * Emit bytecode directly in order to support "old" version of gas. - * - * Opcodes from the Intel architecture reference manual, vol. 3. - * We always use registers, so we don't need prefixes for memory operands. - * Operand macros are in gas order (src, dst) as opposed to Intel order - * (dst, src) in order to blend better into the surrounding assembly code. - */ -#define AESDEC ".byte 0x66,0x0F,0x38,0xDE," -#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF," -#define AESENC ".byte 0x66,0x0F,0x38,0xDC," -#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD," -#define AESIMC ".byte 0x66,0x0F,0x38,0xDB," -#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF," -#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44," - -#define xmm0_xmm0 "0xC0" -#define xmm0_xmm1 "0xC8" -#define xmm0_xmm2 "0xD0" -#define xmm0_xmm3 "0xD8" -#define xmm0_xmm4 "0xE0" -#define xmm1_xmm0 "0xC1" -#define xmm1_xmm2 "0xD1" - -/* - * AES-NI AES-ECB block en(de)cryption - */ -int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - asm( "movdqu (%3), %%xmm0 \n\t" // load input - "movdqu (%1), %%xmm1 \n\t" // load round key 0 - "pxor %%xmm1, %%xmm0 \n\t" // round 0 - "add $16, %1 \n\t" // point to next round key - "subl $1, %0 \n\t" // normal rounds = nr - 1 - "test %2, %2 \n\t" // mode? - "jz 2f \n\t" // 0 = decrypt - - "1: \n\t" // encryption loop - "movdqu (%1), %%xmm1 \n\t" // load round key - AESENC xmm1_xmm0 "\n\t" // do round - "add $16, %1 \n\t" // point to next round key - "subl $1, %0 \n\t" // loop - "jnz 1b \n\t" - "movdqu (%1), %%xmm1 \n\t" // load round key - AESENCLAST xmm1_xmm0 "\n\t" // last round - "jmp 3f \n\t" - - "2: \n\t" // decryption loop - "movdqu (%1), %%xmm1 \n\t" - AESDEC xmm1_xmm0 "\n\t" // do round - "add $16, %1 \n\t" - "subl $1, %0 \n\t" - "jnz 2b \n\t" - "movdqu (%1), %%xmm1 \n\t" // load round key - AESDECLAST xmm1_xmm0 "\n\t" // last round - - "3: \n\t" - "movdqu %%xmm0, (%4) \n\t" // export output - : - : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) - : "memory", "cc", "xmm0", "xmm1" ); - - - return( 0 ); -} - -/* - * GCM multiplication: c = a times b in GF(2^128) - * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. - */ -void mbedtls_aesni_gcm_mult( unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16] ) -{ - unsigned char aa[16], bb[16], cc[16]; - size_t i; - - /* The inputs are in big-endian order, so byte-reverse them */ - for( i = 0; i < 16; i++ ) - { - aa[i] = a[15 - i]; - bb[i] = b[15 - i]; - } - - asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0 - "movdqu (%1), %%xmm1 \n\t" // b1:b0 - - /* - * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 - * using [CLMUL-WP] algorithm 1 (p. 13). - */ - "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 - "movdqa %%xmm1, %%xmm3 \n\t" // same - "movdqa %%xmm1, %%xmm4 \n\t" // same - PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0 - PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0 - PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0 - PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0 - "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 - "movdqa %%xmm4, %%xmm3 \n\t" // same - "psrldq $8, %%xmm4 \n\t" // 0:e1+f1 - "pslldq $8, %%xmm3 \n\t" // e0+f0:0 - "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 - "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 - - /* - * Now shift the result one bit to the left, - * taking advantage of [CLMUL-WP] eq 27 (p. 20) - */ - "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 - "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 - "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 - "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 - "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 - "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 - "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 - "pslldq $8, %%xmm3 \n\t" // r0>>63:0 - "pslldq $8, %%xmm4 \n\t" // r2>>63:0 - "psrldq $8, %%xmm5 \n\t" // 0:r1>>63 - "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 - "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 - "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 - - /* - * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 - * using [CLMUL-WP] algorithm 5 (p. 20). - * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). - */ - /* Step 2 (1) */ - "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 - "movdqa %%xmm1, %%xmm4 \n\t" // same - "movdqa %%xmm1, %%xmm5 \n\t" // same - "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a - "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b - "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c - - /* Step 2 (2) */ - "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b - "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c - "pslldq $8, %%xmm3 \n\t" // a+b+c:0 - "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 - - /* Steps 3 and 4 */ - "movdqa %%xmm1,%%xmm0 \n\t" // d:x0 - "movdqa %%xmm1,%%xmm4 \n\t" // same - "movdqa %%xmm1,%%xmm5 \n\t" // same - "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' - "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' - "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' - "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' - "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' - // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing - // bits carried from d. Now get those\t bits back in. - "movdqa %%xmm1,%%xmm3 \n\t" // d:x0 - "movdqa %%xmm1,%%xmm4 \n\t" // same - "movdqa %%xmm1,%%xmm5 \n\t" // same - "psllq $63, %%xmm3 \n\t" // d<<63:stuff - "psllq $62, %%xmm4 \n\t" // d<<62:stuff - "psllq $57, %%xmm5 \n\t" // d<<57:stuff - "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff - "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff - "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d - "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 - "pxor %%xmm1, %%xmm0 \n\t" // h1:h0 - "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 - - "movdqu %%xmm0, (%2) \n\t" // done - : - : "r" (aa), "r" (bb), "r" (cc) - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" ); - - /* Now byte-reverse the outputs */ - for( i = 0; i < 16; i++ ) - c[i] = cc[15 - i]; - - return; -} - -/* - * Compute decryption round keys from encryption round keys - */ -void mbedtls_aesni_inverse_key( unsigned char *invkey, - const unsigned char *fwdkey, int nr ) -{ - unsigned char *ik = invkey; - const unsigned char *fk = fwdkey + 16 * nr; - - memcpy( ik, fk, 16 ); - - for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 ) - asm( "movdqu (%0), %%xmm0 \n\t" - AESIMC xmm0_xmm0 "\n\t" - "movdqu %%xmm0, (%1) \n\t" - : - : "r" (fk), "r" (ik) - : "memory", "xmm0" ); - - memcpy( ik, fk, 16 ); -} - -/* - * Key expansion, 128-bit case - */ -static void aesni_setkey_enc_128( unsigned char *rk, - const unsigned char *key ) -{ - asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key - "movdqu %%xmm0, (%0) \n\t" // as round key 0 - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next round key. - * - * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff - * with X = rot( sub( r3 ) ) ^ RCON. - * - * On exit, xmm0 is r7:r6:r5:r4 - * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 - * and those are written to the round key buffer. - */ - "1: \n\t" - "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X - "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 - "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 - "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 - "pslldq $4, %%xmm0 \n\t" // etc - "pxor %%xmm0, %%xmm1 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! - "add $16, %0 \n\t" // point to next round key - "movdqu %%xmm0, (%0) \n\t" // write it - "ret \n\t" - - /* Main "loop" */ - "2: \n\t" - AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t" - : - : "r" (rk), "r" (key) - : "memory", "cc", "0" ); -} - -/* - * Key expansion, 192-bit case - */ -static void aesni_setkey_enc_192( unsigned char *rk, - const unsigned char *key ) -{ - asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "movq 16(%1), %%xmm1 \n\t" - "movq %%xmm1, (%0) \n\t" - "add $8, %0 \n\t" - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next 6 quarter-keys. - * - * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 - * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. - * - * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 - * and those are written to the round key buffer. - */ - "1: \n\t" - "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X - "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 - "pslldq $4, %%xmm0 \n\t" // etc - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 - "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 - "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 - "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 - "movq %%xmm1, (%0) \n\t" - "add $8, %0 \n\t" - "ret \n\t" - - "2: \n\t" - AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t" - - : - : "r" (rk), "r" (key) - : "memory", "cc", "0" ); -} - -/* - * Key expansion, 256-bit case - */ -static void aesni_setkey_enc_256( unsigned char *rk, - const unsigned char *key ) -{ - asm( "movdqu (%1), %%xmm0 \n\t" - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "movdqu 16(%1), %%xmm1 \n\t" - "movdqu %%xmm1, (%0) \n\t" - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next two round keys. - * - * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and - * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON - * - * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 - * and those have been written to the output buffer. - */ - "1: \n\t" - "pshufd $0xff, %%xmm2, %%xmm2 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm2, %%xmm0 \n\t" - "add $16, %0 \n\t" - "movdqu %%xmm0, (%0) \n\t" - - /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) - * and proceed to generate next round key from there */ - AESKEYGENA xmm0_xmm2 ",0x00 \n\t" - "pshufd $0xaa, %%xmm2, %%xmm2 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm2, %%xmm1 \n\t" - "add $16, %0 \n\t" - "movdqu %%xmm1, (%0) \n\t" - "ret \n\t" - - /* - * Main "loop" - Generating one more key than necessary, - * see definition of mbedtls_aes_context.buf - */ - "2: \n\t" - AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" - : - : "r" (rk), "r" (key) - : "memory", "cc", "0" ); -} - -/* - * Key expansion, wrapper - */ -int mbedtls_aesni_setkey_enc( unsigned char *rk, - const unsigned char *key, - size_t bits ) -{ - switch( bits ) - { - case 128: aesni_setkey_enc_128( rk, key ); break; - case 192: aesni_setkey_enc_192( rk, key ); break; - case 256: aesni_setkey_enc_256( rk, key ); break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - - return( 0 ); -} - -#endif /* MBEDTLS_HAVE_X86_64 */ - -#endif /* MBEDTLS_AESNI_C */ diff --git a/library/arc4.c b/library/arc4.c deleted file mode 100644 index b8998ac6cd..0000000000 --- a/library/arc4.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * An implementation of the ARCFOUR algorithm - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The ARCFOUR algorithm was publicly disclosed on 94/09. - * - * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ARC4_C) - -#include "mbedtls/arc4.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_ARC4_ALT) - -void mbedtls_arc4_init( mbedtls_arc4_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_arc4_context ) ); -} - -void mbedtls_arc4_free( mbedtls_arc4_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) ); -} - -/* - * ARC4 key schedule - */ -void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, - unsigned int keylen ) -{ - int i, j, a; - unsigned int k; - unsigned char *m; - - ctx->x = 0; - ctx->y = 0; - m = ctx->m; - - for( i = 0; i < 256; i++ ) - m[i] = (unsigned char) i; - - j = k = 0; - - for( i = 0; i < 256; i++, k++ ) - { - if( k >= keylen ) k = 0; - - a = m[i]; - j = ( j + a + key[k] ) & 0xFF; - m[i] = m[j]; - m[j] = (unsigned char) a; - } -} - -/* - * ARC4 cipher function - */ -int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, - unsigned char *output ) -{ - int x, y, a, b; - size_t i; - unsigned char *m; - - x = ctx->x; - y = ctx->y; - m = ctx->m; - - for( i = 0; i < length; i++ ) - { - x = ( x + 1 ) & 0xFF; a = m[x]; - y = ( y + a ) & 0xFF; b = m[y]; - - m[x] = (unsigned char) b; - m[y] = (unsigned char) a; - - output[i] = (unsigned char) - ( input[i] ^ m[(unsigned char)( a + b )] ); - } - - ctx->x = x; - ctx->y = y; - - return( 0 ); -} - -#endif /* !MBEDTLS_ARC4_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: - * - * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 - */ -static const unsigned char arc4_test_key[3][8] = -{ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char arc4_test_pt[3][8] = -{ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char arc4_test_ct[3][8] = -{ - { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, - { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, - { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } -}; - -/* - * Checkup routine - */ -int mbedtls_arc4_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char ibuf[8]; - unsigned char obuf[8]; - mbedtls_arc4_context ctx; - - mbedtls_arc4_init( &ctx ); - - for( i = 0; i < 3; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " ARC4 test #%d: ", i + 1 ); - - memcpy( ibuf, arc4_test_pt[i], 8 ); - - mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 ); - mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf ); - - if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_arc4_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ARC4_C */ diff --git a/library/aria.c b/library/aria.c deleted file mode 100644 index aff66d667f..0000000000 --- a/library/aria.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * ARIA implementation - * - * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * This implementation is based on the following standards: - * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf - * [2] https://tools.ietf.org/html/rfc5794 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ARIA_C) - -#include "mbedtls/aria.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_ARIA_ALT) - -#include "mbedtls/platform_util.h" - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Parameter validation macros */ -#define ARIA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ) -#define ARIA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE( n, b, i ) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE( n, b, i ) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -/* - * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes - * - * This is submatrix P1 in [1] Appendix B.1 - * - * Common compilers fail to translate this to minimal number of instructions, - * so let's provide asm versions for common platforms with C fallback. - */ -#if defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) /* rev16 available from v6 up */ -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ - __ARM_ARCH >= 6 -static inline uint32_t aria_p1( uint32_t x ) -{ - uint32_t r; - __asm( "rev16 %0, %1" : "=l" (r) : "l" (x) ); - return( r ); -} -#define ARIA_P1 aria_p1 -#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ - ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) -static inline uint32_t aria_p1( uint32_t x ) -{ - uint32_t r; - __asm( "rev16 r, x" ); - return( r ); -} -#define ARIA_P1 aria_p1 -#endif -#endif /* arm */ -#if defined(__GNUC__) && \ - defined(__i386__) || defined(__amd64__) || defined( __x86_64__) -/* I couldn't find an Intel equivalent of rev16, so two instructions */ -#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) ) -#endif /* x86 gnuc */ -#endif /* MBEDTLS_HAVE_ASM && GNUC */ -#if !defined(ARIA_P1) -#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8)) -#endif - -/* - * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits - * - * This is submatrix P2 in [1] Appendix B.1 - * - * Common compilers will translate this to a single instruction. - */ -#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16)) - -/* - * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness - * - * This is submatrix P3 in [1] Appendix B.1 - * - * Some compilers fail to translate this to a single instruction, - * so let's provide asm versions for common platforms with C fallback. - */ -#if defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) /* rev available from v6 up */ -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ - __ARM_ARCH >= 6 -static inline uint32_t aria_p3( uint32_t x ) -{ - uint32_t r; - __asm( "rev %0, %1" : "=l" (r) : "l" (x) ); - return( r ); -} -#define ARIA_P3 aria_p3 -#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ - ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) -static inline uint32_t aria_p3( uint32_t x ) -{ - uint32_t r; - __asm( "rev r, x" ); - return( r ); -} -#define ARIA_P3 aria_p3 -#endif -#endif /* arm */ -#if defined(__GNUC__) && \ - defined(__i386__) || defined(__amd64__) || defined( __x86_64__) -static inline uint32_t aria_p3( uint32_t x ) -{ - __asm( "bswap %0" : "=r" (x) : "0" (x) ); - return( x ); -} -#define ARIA_P3 aria_p3 -#endif /* x86 gnuc */ -#endif /* MBEDTLS_HAVE_ASM && GNUC */ -#if !defined(ARIA_P3) -#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) ) -#endif - -/* - * ARIA Affine Transform - * (a, b, c, d) = state in/out - * - * If we denote the first byte of input by 0, ..., the last byte by f, - * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef. - * - * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple - * rearrangements on adjacent pairs, output is: - * - * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe - * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd - * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd - * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc - * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe - * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc - * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef - * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef - * - * Note: another presentation of the A transform can be found as the first - * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4. - * The implementation below uses only P1 and P2 as they are sufficient. - */ -static inline void aria_a( uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d ) -{ - uint32_t ta, tb, tc; - ta = *b; // 4567 - *b = *a; // 0123 - *a = ARIA_P2( ta ); // 6745 - tb = ARIA_P2( *d ); // efcd - *d = ARIA_P1( *c ); // 98ba - *c = ARIA_P1( tb ); // fedc - ta ^= *d; // 4567+98ba - tc = ARIA_P2( *b ); // 2301 - ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc - tb ^= ARIA_P2( *d ); // ba98+efcd - tc ^= ARIA_P1( *a ); // 2301+7654 - *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT - tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc - *a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT - ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe - *d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT - tc = ARIA_P2( tc ); // 0123+5476 - *c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT -} - -/* - * ARIA Substitution Layer SL1 / SL2 - * (a, b, c, d) = state in/out - * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below) - * - * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1 - * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2 - */ -static inline void aria_sl( uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d, - const uint8_t sa[256], const uint8_t sb[256], - const uint8_t sc[256], const uint8_t sd[256] ) -{ - *a = ( (uint32_t) sa[ *a & 0xFF] ) ^ - (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *a >> 24 ]) << 24); - *b = ( (uint32_t) sa[ *b & 0xFF] ) ^ - (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *b >> 24 ]) << 24); - *c = ( (uint32_t) sa[ *c & 0xFF] ) ^ - (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *c >> 24 ]) << 24); - *d = ( (uint32_t) sa[ *d & 0xFF] ) ^ - (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *d >> 24 ]) << 24); -} - -/* - * S-Boxes - */ -static const uint8_t aria_sb1[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, - 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, - 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, - 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, - 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, - 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, - 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, - 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, - 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, - 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, - 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, - 0xB0, 0x54, 0xBB, 0x16 -}; - -static const uint8_t aria_sb2[256] = -{ - 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46, - 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, - 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B, - 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB, - 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA, - 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, - 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38, - 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53, - 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, - 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, - 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD, - 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC, - 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E, - 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A, - 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5, - 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8, - 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, - 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, - 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33, - 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D, - 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, - 0xAF, 0xBA, 0xB5, 0x81 -}; - -static const uint8_t aria_is1[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D -}; - -static const uint8_t aria_is2[256] = -{ - 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1, - 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3, - 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89, - 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D, - 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98, - 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, - 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F, - 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE, - 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, - 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, - 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55, - 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A, - 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE, - 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0, - 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6, - 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5, - 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, - 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, - 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94, - 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3, - 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, - 0x03, 0xA2, 0xAC, 0x60 -}; - -/* - * Helper for key schedule: r = FO( p, k ) ^ x - */ -static void aria_fo_xor( uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4] ) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); - aria_a( &a, &b, &c, &d ); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Helper for key schedule: r = FE( p, k ) ^ x - */ -static void aria_fe_xor( uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4] ) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); - aria_a( &a, &b, &c, &d ); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup. - * - * We chose to store bytes into 32-bit words in little-endian format (see - * GET/PUT_UINT32_LE) so we need to reverse bytes here. - */ -static void aria_rot128( uint32_t r[4], const uint32_t a[4], - const uint32_t b[4], uint8_t n ) -{ - uint8_t i, j; - uint32_t t, u; - - const uint8_t n1 = n % 32; // bit offset - const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset - - j = ( n / 32 ) % 4; // initial word offset - t = ARIA_P3( b[j] ); // big endian - for( i = 0; i < 4; i++ ) - { - j = ( j + 1 ) % 4; // get next word, big endian - u = ARIA_P3( b[j] ); - t <<= n1; // rotate - t |= u >> n2; - t = ARIA_P3( t ); // back to little endian - r[i] = a[i] ^ t; // store - t = u; // move to next word - } -} - -/* - * Set encryption key - */ -int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits ) -{ - /* round constant masks */ - const uint32_t rc[3][4] = - { - { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA }, - { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF }, - { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 } - }; - - int i; - uint32_t w[4][4], *w2; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( key != NULL ); - - if( keybits != 128 && keybits != 192 && keybits != 256 ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - /* Copy key to W0 (and potential remainder to W1) */ - GET_UINT32_LE( w[0][0], key, 0 ); - GET_UINT32_LE( w[0][1], key, 4 ); - GET_UINT32_LE( w[0][2], key, 8 ); - GET_UINT32_LE( w[0][3], key, 12 ); - - memset( w[1], 0, 16 ); - if( keybits >= 192 ) - { - GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key - GET_UINT32_LE( w[1][1], key, 20 ); - } - if( keybits == 256 ) - { - GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key - GET_UINT32_LE( w[1][3], key, 28 ); - } - - i = ( keybits - 128 ) >> 6; // index: 0, 1, 2 - ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16 - - aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR - i = i < 2 ? i + 1 : 0; - aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0 - i = i < 2 ? i + 1 : 0; - aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1 - - for( i = 0; i < 4; i++ ) // create round keys - { - w2 = w[(i + 1) & 3]; - aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 ); - aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 ); - aria_rot128( ctx->rk[i + 8], w[i], w2, 61 ); - aria_rot128( ctx->rk[i + 12], w[i], w2, 31 ); - } - aria_rot128( ctx->rk[16], w[0], w[1], 19 ); - - /* w holds enough info to reconstruct the round keys */ - mbedtls_platform_zeroize( w, sizeof( w ) ); - - return( 0 ); -} - -/* - * Set decryption key - */ -int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits ) -{ - int i, j, k, ret; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aria_setkey_enc( ctx, key, keybits ); - if( ret != 0 ) - return( ret ); - - /* flip the order of round keys */ - for( i = 0, j = ctx->nr; i < j; i++, j-- ) - { - for( k = 0; k < 4; k++ ) - { - uint32_t t = ctx->rk[i][k]; - ctx->rk[i][k] = ctx->rk[j][k]; - ctx->rk[j][k] = t; - } - } - - /* apply affine transform to middle keys */ - for( i = 1; i < ctx->nr; i++ ) - { - aria_a( &ctx->rk[i][0], &ctx->rk[i][1], - &ctx->rk[i][2], &ctx->rk[i][3] ); - } - - return( 0 ); -} - -/* - * Encrypt a block - */ -int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, - const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ) -{ - int i; - - uint32_t a, b, c, d; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( input != NULL ); - ARIA_VALIDATE_RET( output != NULL ); - - GET_UINT32_LE( a, input, 0 ); - GET_UINT32_LE( b, input, 4 ); - GET_UINT32_LE( c, input, 8 ); - GET_UINT32_LE( d, input, 12 ); - - i = 0; - while( 1 ) - { - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); - aria_a( &a, &b, &c, &d ); - - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); - if( i >= ctx->nr ) - break; - aria_a( &a, &b, &c, &d ); - } - - /* final key mixing */ - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - - PUT_UINT32_LE( a, output, 0 ); - PUT_UINT32_LE( b, output, 4 ); - PUT_UINT32_LE( c, output, 8 ); - PUT_UINT32_LE( d, output, 12 ); - - return( 0 ); -} - -/* Initialize context */ -void mbedtls_aria_init( mbedtls_aria_context *ctx ) -{ - ARIA_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_aria_context ) ); -} - -/* Clear context */ -void mbedtls_aria_free( mbedtls_aria_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * ARIA-CBC buffer encryption/decryption - */ -int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE]; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || - mode == MBEDTLS_ARIA_DECRYPT ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( iv != NULL ); - - if( length % MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_ARIA_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE ); - mbedtls_aria_crypt_ecb( ctx, input, output ); - - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE ); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_aria_crypt_ecb( ctx, output, output ); - memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE ); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * ARIA-CFB128 buffer encryption/decryption - */ -int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - unsigned char c; - size_t n; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || - mode == MBEDTLS_ARIA_DECRYPT ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( iv != NULL ); - ARIA_VALIDATE_RET( iv_off != NULL ); - - n = *iv_off; - - /* An overly large value of n can lead to an unlimited - * buffer overflow. Therefore, guard against this - * outside of parameter validation. */ - if( n >= MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_ARIA_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aria_crypt_ecb( ctx, iv, iv ); - - c = *input++; - *output++ = c ^ iv[n]; - iv[n] = c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aria_crypt_ecb( ctx, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * ARIA-CTR buffer encryption/decryption - */ -int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( nonce_counter != NULL ); - ARIA_VALIDATE_RET( stream_block != NULL ); - ARIA_VALIDATE_RET( nc_off != NULL ); - - n = *nc_off; - /* An overly large value of n can lead to an unlimited - * buffer overflow. Therefore, guard against this - * outside of parameter validation. */ - if( n >= MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_aria_crypt_ecb( ctx, nonce_counter, - stream_block ); - - for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* !MBEDTLS_ARIA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Basic ARIA ECB test vectors from RFC 5794 - */ -static const uint8_t aria_test1_ecb_key[32] = // test key -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit -}; - -static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] = // plaintext -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes -}; - -static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] = // ciphertext -{ - { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit - 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 }, - { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit - 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 }, - { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit - 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC } -}; - -/* - * Mode tests from "Test Vectors for ARIA" Version 1.0 - * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf - */ -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) -static const uint8_t aria_test2_key[32] = -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit -}; - -static const uint8_t aria_test2_pt[48] = -{ - 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all - 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb, - 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, - 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd, - 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa, - 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb, -}; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)) -static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] = -{ - 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB - 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV -}; -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertext -{ - { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key - 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34, - 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64, - 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38, - 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c, - 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 }, - { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key - 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f, - 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1, - 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5, - 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92, - 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e }, - { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key - 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab, - 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef, - 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52, - 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5, - 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertext -{ - { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key - 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00, - 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a, - 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01, - 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96, - 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b }, - { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key - 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c, - 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94, - 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59, - 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86, - 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b }, - { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key - 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35, - 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70, - 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa, - 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c, - 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext -{ - { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key - 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1, - 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1, - 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f, - 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71, - 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 }, - { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key - 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce, - 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde, - 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79, - 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce, - 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf }, - { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key - 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2, - 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89, - 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f, - 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7, - 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#define ARIA_SELF_TEST_IF_FAIL \ - { \ - if( verbose ) \ - mbedtls_printf( "failed\n" ); \ - return( 1 ); \ - } else { \ - if( verbose ) \ - mbedtls_printf( "passed\n" ); \ - } - -/* - * Checkup routine - */ -int mbedtls_aria_self_test( int verbose ) -{ - int i; - uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE]; - mbedtls_aria_context ctx; - -#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR)) - size_t j; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \ - defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) - uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE]; -#endif - - /* - * Test set 1 - */ - for( i = 0; i < 3; i++ ) - { - /* test ECB encryption */ - if( verbose ) - mbedtls_printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i ); - mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk ); - if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* test ECB decryption */ - if( verbose ) - mbedtls_printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i ); - mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk ); - if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); - - /* - * Test set 2 - */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) - for( i = 0; i < 3; i++ ) - { - /* Test CBC encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0x55, sizeof( buf ) ); - mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CBC decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0xAA, sizeof( buf ) ); - mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv, - aria_test2_cbc_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); - -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - for( i = 0; i < 3; i++ ) - { - /* Test CFB encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0x55, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CFB decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0xAA, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j, - iv, aria_test2_cfb_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - for( i = 0; i < 3; i++ ) - { - /* Test CTR encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 - memset( buf, 0x55, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CTR decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 - memset( buf, 0xAA, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, - aria_test2_ctr_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ARIA_C */ diff --git a/library/asn1parse.c b/library/asn1parse.c deleted file mode 100644 index 171c340b8c..0000000000 --- a/library/asn1parse.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Generic ASN.1 parsing - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) - -#include "mbedtls/asn1.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -/* - * ASN.1 DER decoding routines - */ -int mbedtls_asn1_get_len( unsigned char **p, - const unsigned char *end, - size_t *len ) -{ - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( ( **p & 0x80 ) == 0 ) - *len = *(*p)++; - else - { - switch( **p & 0x7F ) - { - case 1: - if( ( end - *p ) < 2 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = (*p)[1]; - (*p) += 2; - break; - - case 2: - if( ( end - *p ) < 3 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; - (*p) += 3; - break; - - case 3: - if( ( end - *p ) < 4 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = ( (size_t)(*p)[1] << 16 ) | - ( (size_t)(*p)[2] << 8 ) | (*p)[3]; - (*p) += 4; - break; - - case 4: - if( ( end - *p ) < 5 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | - ( (size_t)(*p)[3] << 8 ) | (*p)[4]; - (*p) += 5; - break; - - default: - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - } - } - - if( *len > (size_t) ( end - *p ) ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - return( 0 ); -} - -int mbedtls_asn1_get_tag( unsigned char **p, - const unsigned char *end, - size_t *len, int tag ) -{ - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( **p != tag ) - return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - (*p)++; - - return( mbedtls_asn1_get_len( p, end, len ) ); -} - -int mbedtls_asn1_get_bool( unsigned char **p, - const unsigned char *end, - int *val ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) - return( ret ); - - if( len != 1 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - *val = ( **p != 0 ) ? 1 : 0; - (*p)++; - - return( 0 ); -} - -int mbedtls_asn1_get_int( unsigned char **p, - const unsigned char *end, - int *val ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( ret ); - - if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - *val = 0; - - while( len-- > 0 ) - { - *val = ( *val << 8 ) | **p; - (*p)++; - } - - return( 0 ); -} - -#if defined(MBEDTLS_BIGNUM_C) -int mbedtls_asn1_get_mpi( unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( ret ); - - ret = mbedtls_mpi_read_binary( X, *p, len ); - - *p += len; - - return( ret ); -} -#endif /* MBEDTLS_BIGNUM_C */ - -int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, - mbedtls_asn1_bitstring *bs) -{ - int ret; - - /* Certificate type is a single byte bitstring */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) - return( ret ); - - /* Check length, subtract one for actual bit string length */ - if( bs->len < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - bs->len -= 1; - - /* Get number of unused bits, ensure unused bits <= 7 */ - bs->unused_bits = **p; - if( bs->unused_bits > 7 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - (*p)++; - - /* Get actual bitstring */ - bs->p = *p; - *p += bs->len; - - if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Get a bit string without unused bits - */ -int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, - size_t *len ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) - return( ret ); - - if( (*len)-- < 2 || *(*p)++ != 0 ) - return( MBEDTLS_ERR_ASN1_INVALID_DATA ); - - return( 0 ); -} - - - -/* - * Parses and splits an ASN.1 "SEQUENCE OF " - */ -int mbedtls_asn1_get_sequence_of( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_sequence *cur, - int tag) -{ - int ret; - size_t len; - mbedtls_asn1_buf *buf; - - /* Get main sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - buf = &(cur->buf); - buf->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) - return( ret ); - - buf->p = *p; - *p += buf->len; - - /* Allocate and assign next pointer */ - if( *p < end ) - { - cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, - sizeof( mbedtls_asn1_sequence ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - - cur = cur->next; - } - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -int mbedtls_asn1_get_alg( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - alg->tag = **p; - end = *p + len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( ret ); - - alg->p = *p; - *p += alg->len; - - if( *p == end ) - { - mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) ); - return( 0 ); - } - - params->tag = **p; - (*p)++; - - if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) - return( ret ); - - params->p = *p; - *p += params->len; - - if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -int mbedtls_asn1_get_alg_null( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg ) -{ - int ret; - mbedtls_asn1_buf params; - - memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); - - if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) - return( ret ); - - if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) - return( MBEDTLS_ERR_ASN1_INVALID_DATA ); - - return( 0 ); -} - -void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) -{ - if( cur == NULL ) - return; - - mbedtls_free( cur->oid.p ); - mbedtls_free( cur->val.p ); - - mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); -} - -void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) -{ - mbedtls_asn1_named_data *cur; - - while( ( cur = *head ) != NULL ) - { - *head = cur->next; - mbedtls_asn1_free_named_data( cur ); - mbedtls_free( cur ); - } -} - -mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, - const char *oid, size_t len ) -{ - while( list != NULL ) - { - if( list->oid.len == len && - memcmp( list->oid.p, oid, len ) == 0 ) - { - break; - } - - list = list->next; - } - - return( list ); -} - -#endif /* MBEDTLS_ASN1_PARSE_C */ diff --git a/library/asn1write.c b/library/asn1write.c deleted file mode 100644 index b54e26bd8a..0000000000 --- a/library/asn1write.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * ASN.1 buffer writing functionality - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ASN1_WRITE_C) - -#include "mbedtls/asn1write.h" - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) -{ - if( len < 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = (unsigned char) len; - return( 1 ); - } - - if( len <= 0xFF ) - { - if( *p - start < 2 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = (unsigned char) len; - *--(*p) = 0x81; - return( 2 ); - } - - if( len <= 0xFFFF ) - { - if( *p - start < 3 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = ( len ) & 0xFF; - *--(*p) = ( len >> 8 ) & 0xFF; - *--(*p) = 0x82; - return( 3 ); - } - - if( len <= 0xFFFFFF ) - { - if( *p - start < 4 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = ( len ) & 0xFF; - *--(*p) = ( len >> 8 ) & 0xFF; - *--(*p) = ( len >> 16 ) & 0xFF; - *--(*p) = 0x83; - return( 4 ); - } - -#if SIZE_MAX > 0xFFFFFFFF - if( len <= 0xFFFFFFFF ) -#endif - { - if( *p - start < 5 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = ( len ) & 0xFF; - *--(*p) = ( len >> 8 ) & 0xFF; - *--(*p) = ( len >> 16 ) & 0xFF; - *--(*p) = ( len >> 24 ) & 0xFF; - *--(*p) = 0x84; - return( 5 ); - } - -#if SIZE_MAX > 0xFFFFFFFF - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); -#endif -} - -int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) -{ - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = tag; - - return( 1 ); -} - -int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ) -{ - size_t len = 0; - - if( *p < start || (size_t)( *p - start ) < size ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len = size; - (*p) -= len; - memcpy( *p, buf, len ); - - return( (int) len ); -} - -#if defined(MBEDTLS_BIGNUM_C) -int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ) -{ - int ret; - size_t len = 0; - - // Write the MPI - // - len = mbedtls_mpi_size( X ); - - if( *p < start || (size_t)( *p - start ) < len ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - (*p) -= len; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) ); - - // DER format assumes 2s complement for numbers, so the leftmost bit - // should be 0 for positive numbers and 1 for negative numbers. - // - if( X->s ==1 && **p & 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = 0x00; - len += 1; - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); - - ret = (int) len; - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_BIGNUM_C */ - -int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ) -{ - int ret; - size_t len = 0; - - // Write NULL - // - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len ) -{ - int ret; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) oid, oid_len ) ); - MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len ) -{ - int ret; - size_t len = 0; - - if( par_len == 0 ) - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) ); - else - len += par_len; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) -{ - int ret; - size_t len = 0; - - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = (boolean) ? 255 : 0; - len++; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) -{ - int ret; - size_t len = 0; - - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len += 1; - *--(*p) = val; - - if( val > 0 && **p & 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = 0x00; - len += 1; - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag, - const char *text, size_t text_len ) -{ - int ret; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) text, text_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) ); -} - -int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) ); -} - -int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) ); -} - -int mbedtls_asn1_write_named_bitstring( unsigned char **p, - unsigned char *start, - const unsigned char *buf, - size_t bits ) -{ - size_t unused_bits, byte_len; - const unsigned char *cur_byte; - unsigned char cur_byte_shifted; - unsigned char bit; - - byte_len = ( bits + 7 ) / 8; - unused_bits = ( byte_len * 8 ) - bits; - - /* - * Named bitstrings require that trailing 0s are excluded in the encoding - * of the bitstring. Trailing 0s are considered part of the 'unused' bits - * when encoding this value in the first content octet - */ - if( bits != 0 ) - { - cur_byte = buf + byte_len - 1; - cur_byte_shifted = *cur_byte >> unused_bits; - - for( ; ; ) - { - bit = cur_byte_shifted & 0x1; - cur_byte_shifted >>= 1; - - if( bit != 0 ) - break; - - bits--; - if( bits == 0 ) - break; - - if( bits % 8 == 0 ) - cur_byte_shifted = *--cur_byte; - } - } - - return( mbedtls_asn1_write_bitstring( p, start, buf, bits ) ); -} - -int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t bits ) -{ - int ret; - size_t len = 0; - size_t unused_bits, byte_len; - - byte_len = ( bits + 7 ) / 8; - unused_bits = ( byte_len * 8 ) - bits; - - if( *p < start || (size_t)( *p - start ) < byte_len + 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len = byte_len + 1; - - /* Write the bitstring. Ensure the unused bits are zeroed */ - if( byte_len > 0 ) - { - byte_len--; - *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 ); - ( *p ) -= byte_len; - memcpy( *p, buf, byte_len ); - } - - /* Write unused bits */ - *--( *p ) = (unsigned char)unused_bits; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ) -{ - int ret; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); - - return( (int) len ); -} - - -/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(), - * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */ -static mbedtls_asn1_named_data *asn1_find_named_data( - mbedtls_asn1_named_data *list, - const char *oid, size_t len ) -{ - while( list != NULL ) - { - if( list->oid.len == len && - memcmp( list->oid.p, oid, len ) == 0 ) - { - break; - } - - list = list->next; - } - - return( list ); -} - -mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( - mbedtls_asn1_named_data **head, - const char *oid, size_t oid_len, - const unsigned char *val, - size_t val_len ) -{ - mbedtls_asn1_named_data *cur; - - if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) - { - // Add new entry if not present yet based on OID - // - cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, - sizeof(mbedtls_asn1_named_data) ); - if( cur == NULL ) - return( NULL ); - - cur->oid.len = oid_len; - cur->oid.p = mbedtls_calloc( 1, oid_len ); - if( cur->oid.p == NULL ) - { - mbedtls_free( cur ); - return( NULL ); - } - - memcpy( cur->oid.p, oid, oid_len ); - - cur->val.len = val_len; - cur->val.p = mbedtls_calloc( 1, val_len ); - if( cur->val.p == NULL ) - { - mbedtls_free( cur->oid.p ); - mbedtls_free( cur ); - return( NULL ); - } - - cur->next = *head; - *head = cur; - } - else if( cur->val.len < val_len ) - { - /* - * Enlarge existing value buffer if needed - * Preserve old data until the allocation succeeded, to leave list in - * a consistent state in case allocation fails. - */ - void *p = mbedtls_calloc( 1, val_len ); - if( p == NULL ) - return( NULL ); - - mbedtls_free( cur->val.p ); - cur->val.p = p; - cur->val.len = val_len; - } - - if( val != NULL ) - memcpy( cur->val.p, val, val_len ); - - return( cur ); -} -#endif /* MBEDTLS_ASN1_WRITE_C */ diff --git a/library/base64.c b/library/base64.c deleted file mode 100644 index f06b57b31f..0000000000 --- a/library/base64.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * RFC 1521 base64 encoding/decoding - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_BASE64_C) - -#include "mbedtls/base64.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#include -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -static const unsigned char base64_enc_map[64] = -{ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/' -}; - -static const unsigned char base64_dec_map[128] = -{ - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, - 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 127, 127, 127, 127, 127 -}; - -#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ - -/* - * Encode a buffer into base64 format - */ -int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ) -{ - size_t i, n; - int C1, C2, C3; - unsigned char *p; - - if( slen == 0 ) - { - *olen = 0; - return( 0 ); - } - - n = slen / 3 + ( slen % 3 != 0 ); - - if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 ) - { - *olen = BASE64_SIZE_T_MAX; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - n *= 4; - - if( ( dlen < n + 1 ) || ( NULL == dst ) ) - { - *olen = n + 1; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - n = ( slen / 3 ) * 3; - - for( i = 0, p = dst; i < n; i += 3 ) - { - C1 = *src++; - C2 = *src++; - C3 = *src++; - - *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; - *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; - *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; - *p++ = base64_enc_map[C3 & 0x3F]; - } - - if( i < slen ) - { - C1 = *src++; - C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; - - *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; - *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; - - if( ( i + 1 ) < slen ) - *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; - else *p++ = '='; - - *p++ = '='; - } - - *olen = p - dst; - *p = 0; - - return( 0 ); -} - -/* - * Decode a base64-formatted buffer - */ -int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ) -{ - size_t i, n; - uint32_t j, x; - unsigned char *p; - - /* First pass: check for validity and get output length */ - for( i = n = j = 0; i < slen; i++ ) - { - /* Skip spaces before checking for EOL */ - x = 0; - while( i < slen && src[i] == ' ' ) - { - ++i; - ++x; - } - - /* Spaces at end of buffer are OK */ - if( i == slen ) - break; - - if( ( slen - i ) >= 2 && - src[i] == '\r' && src[i + 1] == '\n' ) - continue; - - if( src[i] == '\n' ) - continue; - - /* Space inside a line is an error */ - if( x != 0 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( src[i] == '=' && ++j > 2 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( base64_dec_map[src[i]] < 64 && j != 0 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - n++; - } - - if( n == 0 ) - { - *olen = 0; - return( 0 ); - } - - /* The following expression is to calculate the following formula without - * risk of integer overflow in n: - * n = ( ( n * 6 ) + 7 ) >> 3; - */ - n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 ); - n -= j; - - if( dst == NULL || dlen < n ) - { - *olen = n; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) - { - if( *src == '\r' || *src == '\n' || *src == ' ' ) - continue; - - j -= ( base64_dec_map[*src] == 64 ); - x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); - - if( ++n == 4 ) - { - n = 0; - if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); - if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); - if( j > 2 ) *p++ = (unsigned char)( x ); - } - } - - *olen = p - dst; - - return( 0 ); -} - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char base64_test_dec[64] = -{ - 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, - 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, - 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, - 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, - 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, - 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, - 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, - 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 -}; - -static const unsigned char base64_test_enc[] = - "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" - "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; - -/* - * Checkup routine - */ -int mbedtls_base64_self_test( int verbose ) -{ - size_t len; - const unsigned char *src; - unsigned char buffer[128]; - - if( verbose != 0 ) - mbedtls_printf( " Base64 encoding test: " ); - - src = base64_test_dec; - - if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 || - memcmp( base64_test_enc, buffer, 88 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n Base64 decoding test: " ); - - src = base64_test_enc; - - if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 || - memcmp( base64_test_dec, buffer, 64 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_BASE64_C */ diff --git a/library/bignum.c b/library/bignum.c deleted file mode 100644 index 98ee12a71a..0000000000 --- a/library/bignum.c +++ /dev/null @@ -1,2837 +0,0 @@ -/* - * Multi-precision integer library - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * The following sources were referenced in the design of this Multi-precision - * Integer library: - * - * [1] Handbook of Applied Cryptography - 1997 - * Menezes, van Oorschot and Vanstone - * - * [2] Multi-Precision Math - * Tom St Denis - * https://github.com/libtom/libtommath/blob/develop/tommath.pdf - * - * [3] GNU Multi-Precision Arithmetic Library - * https://gmplib.org/manual/index.html - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_BIGNUM_C) - -#include "mbedtls/bignum.h" -#include "mbedtls/bn_mul.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#define MPI_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA ) -#define MPI_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ -#define biL (ciL << 3) /* bits in limb */ -#define biH (ciL << 2) /* half limb size */ - -#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ - -/* - * Convert between bits/chars and number of limbs - * Divide first in order to avoid potential overflows - */ -#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) -#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) -{ - mbedtls_platform_zeroize( v, ciL * n ); -} - -/* - * Initialize one MPI - */ -void mbedtls_mpi_init( mbedtls_mpi *X ) -{ - MPI_VALIDATE( X != NULL ); - - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Unallocate one MPI - */ -void mbedtls_mpi_free( mbedtls_mpi *X ) -{ - if( X == NULL ) - return; - - if( X->p != NULL ) - { - mbedtls_mpi_zeroize( X->p, X->n ); - mbedtls_free( X->p ); - } - - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Enlarge to the specified number of limbs - */ -int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ) -{ - mbedtls_mpi_uint *p; - MPI_VALIDATE_RET( X != NULL ); - - if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - if( X->n < nblimbs ) - { - if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - if( X->p != NULL ) - { - memcpy( p, X->p, X->n * ciL ); - mbedtls_mpi_zeroize( X->p, X->n ); - mbedtls_free( X->p ); - } - - X->n = nblimbs; - X->p = p; - } - - return( 0 ); -} - -/* - * Resize down as much as possible, - * while keeping at least the specified number of limbs - */ -int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) -{ - mbedtls_mpi_uint *p; - size_t i; - MPI_VALIDATE_RET( X != NULL ); - - if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - /* Actually resize up in this case */ - if( X->n <= nblimbs ) - return( mbedtls_mpi_grow( X, nblimbs ) ); - - for( i = X->n - 1; i > 0; i-- ) - if( X->p[i] != 0 ) - break; - i++; - - if( i < nblimbs ) - i = nblimbs; - - if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - if( X->p != NULL ) - { - memcpy( p, X->p, i * ciL ); - mbedtls_mpi_zeroize( X->p, X->n ); - mbedtls_free( X->p ); - } - - X->n = i; - X->p = p; - - return( 0 ); -} - -/* - * Copy the contents of Y into X - */ -int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ) -{ - int ret = 0; - size_t i; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - if( X == Y ) - return( 0 ); - - if( Y->p == NULL ) - { - mbedtls_mpi_free( X ); - return( 0 ); - } - - for( i = Y->n - 1; i > 0; i-- ) - if( Y->p[i] != 0 ) - break; - i++; - - X->s = Y->s; - - if( X->n < i ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) ); - } - else - { - memset( X->p + i, 0, ( X->n - i ) * ciL ); - } - - memcpy( X->p, Y->p, i * ciL ); - -cleanup: - - return( ret ); -} - -/* - * Swap the contents of X and Y - */ -void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) -{ - mbedtls_mpi T; - MPI_VALIDATE( X != NULL ); - MPI_VALIDATE( Y != NULL ); - - memcpy( &T, X, sizeof( mbedtls_mpi ) ); - memcpy( X, Y, sizeof( mbedtls_mpi ) ); - memcpy( Y, &T, sizeof( mbedtls_mpi ) ); -} - -/* - * Conditionally assign X = Y, without leaking information - * about whether the assignment was made or not. - * (Leaking information about the respective sizes of X and Y is ok however.) - */ -int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ) -{ - int ret = 0; - size_t i; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - /* make sure assign is 0 or 1 in a time-constant manner */ - assign = (assign | (unsigned char)-assign) >> 7; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); - - X->s = X->s * ( 1 - assign ) + Y->s * assign; - - for( i = 0; i < Y->n; i++ ) - X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign; - - for( ; i < X->n; i++ ) - X->p[i] *= ( 1 - assign ); - -cleanup: - return( ret ); -} - -/* - * Conditionally swap X and Y, without leaking information - * about whether the swap was made or not. - * Here it is not ok to simply swap the pointers, which whould lead to - * different memory access patterns when X and Y are used afterwards. - */ -int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap ) -{ - int ret, s; - size_t i; - mbedtls_mpi_uint tmp; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - if( X == Y ) - return( 0 ); - - /* make sure swap is 0 or 1 in a time-constant manner */ - swap = (swap | (unsigned char)-swap) >> 7; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) ); - - s = X->s; - X->s = X->s * ( 1 - swap ) + Y->s * swap; - Y->s = Y->s * ( 1 - swap ) + s * swap; - - - for( i = 0; i < X->n; i++ ) - { - tmp = X->p[i]; - X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap; - Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap; - } - -cleanup: - return( ret ); -} - -/* - * Set value from integer - */ -int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ) -{ - int ret; - MPI_VALIDATE_RET( X != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) ); - memset( X->p, 0, X->n * ciL ); - - X->p[0] = ( z < 0 ) ? -z : z; - X->s = ( z < 0 ) ? -1 : 1; - -cleanup: - - return( ret ); -} - -/* - * Get a specific bit - */ -int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ) -{ - MPI_VALIDATE_RET( X != NULL ); - - if( X->n * biL <= pos ) - return( 0 ); - - return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); -} - -/* Get a specific byte, without range checks. */ -#define GET_BYTE( X, i ) \ - ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff ) - -/* - * Set a bit to a specific value of 0 or 1 - */ -int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ) -{ - int ret = 0; - size_t off = pos / biL; - size_t idx = pos % biL; - MPI_VALIDATE_RET( X != NULL ); - - if( val != 0 && val != 1 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( X->n * biL <= pos ) - { - if( val == 0 ) - return( 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) ); - } - - X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx ); - X->p[off] |= (mbedtls_mpi_uint) val << idx; - -cleanup: - - return( ret ); -} - -/* - * Return the number of less significant zero-bits - */ -size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ) -{ - size_t i, j, count = 0; - MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 ); - - for( i = 0; i < X->n; i++ ) - for( j = 0; j < biL; j++, count++ ) - if( ( ( X->p[i] >> j ) & 1 ) != 0 ) - return( count ); - - return( 0 ); -} - -/* - * Count leading zero bits in a given integer - */ -static size_t mbedtls_clz( const mbedtls_mpi_uint x ) -{ - size_t j; - mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); - - for( j = 0; j < biL; j++ ) - { - if( x & mask ) break; - - mask >>= 1; - } - - return j; -} - -/* - * Return the number of bits - */ -size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ) -{ - size_t i, j; - - if( X->n == 0 ) - return( 0 ); - - for( i = X->n - 1; i > 0; i-- ) - if( X->p[i] != 0 ) - break; - - j = biL - mbedtls_clz( X->p[i] ); - - return( ( i * biL ) + j ); -} - -/* - * Return the total size in bytes - */ -size_t mbedtls_mpi_size( const mbedtls_mpi *X ) -{ - return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 ); -} - -/* - * Convert an ASCII character to digit value - */ -static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c ) -{ - *d = 255; - - if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; - if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; - if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; - - if( *d >= (mbedtls_mpi_uint) radix ) - return( MBEDTLS_ERR_MPI_INVALID_CHARACTER ); - - return( 0 ); -} - -/* - * Import from an ASCII string - */ -int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) -{ - int ret; - size_t i, j, slen, n; - mbedtls_mpi_uint d; - mbedtls_mpi T; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( s != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &T ); - - slen = strlen( s ); - - if( radix == 16 ) - { - if( slen > MPI_SIZE_T_MAX >> 2 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - n = BITS_TO_LIMBS( slen << 2 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - for( i = slen, j = 0; i > 0; i--, j++ ) - { - if( i == 1 && s[i - 1] == '-' ) - { - X->s = -1; - break; - } - - MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); - X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - for( i = 0; i < slen; i++ ) - { - if( i == 0 && s[i] == '-' ) - { - X->s = -1; - continue; - } - - MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) ); - - if( X->s == 1 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) ); - } - } - } - -cleanup: - - mbedtls_mpi_free( &T ); - - return( ret ); -} - -/* - * Helper to write the digits high-order first. - */ -static int mpi_write_hlp( mbedtls_mpi *X, int radix, - char **p, const size_t buflen ) -{ - int ret; - mbedtls_mpi_uint r; - size_t length = 0; - char *p_end = *p + buflen; - - do - { - if( length >= buflen ) - { - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); - /* - * Write the residue in the current position, as an ASCII character. - */ - if( r < 0xA ) - *(--p_end) = (char)( '0' + r ); - else - *(--p_end) = (char)( 'A' + ( r - 0xA ) ); - - length++; - } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 ); - - memmove( *p, p_end, length ); - *p += length; - -cleanup: - - return( ret ); -} - -/* - * Export into an ASCII string - */ -int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, - char *buf, size_t buflen, size_t *olen ) -{ - int ret = 0; - size_t n; - char *p; - mbedtls_mpi T; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( olen != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */ - if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present - * `n`. If radix > 4, this might be a strict - * overapproximation of the number of - * radix-adic digits needed to present `n`. */ - if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to - * present `n`. */ - - n += 1; /* Terminating null byte */ - n += 1; /* Compensate for the divisions above, which round down `n` - * in case it's not even. */ - n += 1; /* Potential '-'-sign. */ - n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing, - * which always uses an even number of hex-digits. */ - - if( buflen < n ) - { - *olen = n; - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - } - - p = buf; - mbedtls_mpi_init( &T ); - - if( X->s == -1 ) - { - *p++ = '-'; - buflen--; - } - - if( radix == 16 ) - { - int c; - size_t i, j, k; - - for( i = X->n, k = 0; i > 0; i-- ) - { - for( j = ciL; j > 0; j-- ) - { - c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; - - if( c == 0 && k == 0 && ( i + j ) != 2 ) - continue; - - *(p++) = "0123456789ABCDEF" [c / 16]; - *(p++) = "0123456789ABCDEF" [c % 16]; - k = 1; - } - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) ); - - if( T.s == -1 ) - T.s = 1; - - MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) ); - } - - *p++ = '\0'; - *olen = p - buf; - -cleanup: - - mbedtls_mpi_free( &T ); - - return( ret ); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Read X from an opened file - */ -int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ) -{ - mbedtls_mpi_uint d; - size_t slen; - char *p; - /* - * Buffer should have space for (short) label and decimal formatted MPI, - * newline characters and '\0' - */ - char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( fin != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - memset( s, 0, sizeof( s ) ); - if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) - return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); - - slen = strlen( s ); - if( slen == sizeof( s ) - 2 ) - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - - if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } - if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } - - p = s + slen; - while( p-- > s ) - if( mpi_get_digit( &d, radix, *p ) != 0 ) - break; - - return( mbedtls_mpi_read_string( X, radix, p + 1 ) ); -} - -/* - * Write X into an opened file (or stdout if fout == NULL) - */ -int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout ) -{ - int ret; - size_t n, slen, plen; - /* - * Buffer should have space for (short) label and decimal formatted MPI, - * newline characters and '\0' - */ - char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; - MPI_VALIDATE_RET( X != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - memset( s, 0, sizeof( s ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) ); - - if( p == NULL ) p = ""; - - plen = strlen( p ); - slen = strlen( s ); - s[slen++] = '\r'; - s[slen++] = '\n'; - - if( fout != NULL ) - { - if( fwrite( p, 1, plen, fout ) != plen || - fwrite( s, 1, slen, fout ) != slen ) - return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); - } - else - mbedtls_printf( "%s%s", p, s ); - -cleanup: - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - - -/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint - * into the storage form used by mbedtls_mpi. */ - -static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x ) -{ - uint8_t i; - mbedtls_mpi_uint tmp = 0; - /* This works regardless of the endianness. */ - for( i = 0; i < ciL; i++, x >>= 8 ) - tmp |= ( x & 0xFF ) << ( ( ciL - 1 - i ) << 3 ); - return( tmp ); -} - -static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x ) -{ -#if defined(__BYTE_ORDER__) - -/* Nothing to do on bigendian systems. */ -#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) - return( x ); -#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */ - -#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) - -/* For GCC and Clang, have builtins for byte swapping. */ -#if defined(__GNUC__) && defined(__GNUC_PREREQ) -#if __GNUC_PREREQ(4,3) -#define have_bswap -#endif -#endif - -#if defined(__clang__) && defined(__has_builtin) -#if __has_builtin(__builtin_bswap32) && \ - __has_builtin(__builtin_bswap64) -#define have_bswap -#endif -#endif - -#if defined(have_bswap) - /* The compiler is hopefully able to statically evaluate this! */ - switch( sizeof(mbedtls_mpi_uint) ) - { - case 4: - return( __builtin_bswap32(x) ); - case 8: - return( __builtin_bswap64(x) ); - } -#endif -#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ -#endif /* __BYTE_ORDER__ */ - - /* Fall back to C-based reordering if we don't know the byte order - * or we couldn't use a compiler-specific builtin. */ - return( mpi_uint_bigendian_to_host_c( x ) ); -} - -static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs ) -{ - mbedtls_mpi_uint *cur_limb_left; - mbedtls_mpi_uint *cur_limb_right; - if( limbs == 0 ) - return; - - /* - * Traverse limbs and - * - adapt byte-order in each limb - * - swap the limbs themselves. - * For that, simultaneously traverse the limbs from left to right - * and from right to left, as long as the left index is not bigger - * than the right index (it's not a problem if limbs is odd and the - * indices coincide in the last iteration). - */ - for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 ); - cur_limb_left <= cur_limb_right; - cur_limb_left++, cur_limb_right-- ) - { - mbedtls_mpi_uint tmp; - /* Note that if cur_limb_left == cur_limb_right, - * this code effectively swaps the bytes only once. */ - tmp = mpi_uint_bigendian_to_host( *cur_limb_left ); - *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right ); - *cur_limb_right = tmp; - } -} - -/* - * Import X from unsigned binary data, little endian - */ -int mbedtls_mpi_read_binary_le( mbedtls_mpi *X, - const unsigned char *buf, size_t buflen ) -{ - int ret; - size_t i; - size_t const limbs = CHARS_TO_LIMBS( buflen ); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - if( X->n != limbs ) - { - mbedtls_mpi_free( X ); - mbedtls_mpi_init( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - for( i = 0; i < buflen; i++ ) - X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3); - -cleanup: - - /* - * This function is also used to import keys. However, wiping the buffers - * upon failure is not necessary because failure only can happen before any - * input is copied. - */ - return( ret ); -} - -/* - * Import X from unsigned binary data, big endian - */ -int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) -{ - int ret; - size_t const limbs = CHARS_TO_LIMBS( buflen ); - size_t const overhead = ( limbs * ciL ) - buflen; - unsigned char *Xp; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - if( X->n != limbs ) - { - mbedtls_mpi_free( X ); - mbedtls_mpi_init( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); - } - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - /* Avoid calling `memcpy` with NULL source argument, - * even if buflen is 0. */ - if( buf != NULL ) - { - Xp = (unsigned char*) X->p; - memcpy( Xp + overhead, buf, buflen ); - - mpi_bigendian_to_host( X->p, limbs ); - } - -cleanup: - - /* - * This function is also used to import keys. However, wiping the buffers - * upon failure is not necessary because failure only can happen before any - * input is copied. - */ - return( ret ); -} - -/* - * Export X into unsigned binary data, little endian - */ -int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X, - unsigned char *buf, size_t buflen ) -{ - size_t stored_bytes = X->n * ciL; - size_t bytes_to_copy; - size_t i; - - if( stored_bytes < buflen ) - { - bytes_to_copy = stored_bytes; - } - else - { - bytes_to_copy = buflen; - - /* The output buffer is smaller than the allocated size of X. - * However X may fit if its leading bytes are zero. */ - for( i = bytes_to_copy; i < stored_bytes; i++ ) - { - if( GET_BYTE( X, i ) != 0 ) - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - } - } - - for( i = 0; i < bytes_to_copy; i++ ) - buf[i] = GET_BYTE( X, i ); - - if( stored_bytes < buflen ) - { - /* Write trailing 0 bytes */ - memset( buf + stored_bytes, 0, buflen - stored_bytes ); - } - - return( 0 ); -} - -/* - * Export X into unsigned binary data, big endian - */ -int mbedtls_mpi_write_binary( const mbedtls_mpi *X, - unsigned char *buf, size_t buflen ) -{ - size_t stored_bytes; - size_t bytes_to_copy; - unsigned char *p; - size_t i; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); - - stored_bytes = X->n * ciL; - - if( stored_bytes < buflen ) - { - /* There is enough space in the output buffer. Write initial - * null bytes and record the position at which to start - * writing the significant bytes. In this case, the execution - * trace of this function does not depend on the value of the - * number. */ - bytes_to_copy = stored_bytes; - p = buf + buflen - stored_bytes; - memset( buf, 0, buflen - stored_bytes ); - } - else - { - /* The output buffer is smaller than the allocated size of X. - * However X may fit if its leading bytes are zero. */ - bytes_to_copy = buflen; - p = buf; - for( i = bytes_to_copy; i < stored_bytes; i++ ) - { - if( GET_BYTE( X, i ) != 0 ) - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - } - } - - for( i = 0; i < bytes_to_copy; i++ ) - p[bytes_to_copy - i - 1] = GET_BYTE( X, i ); - - return( 0 ); -} - -/* - * Left-shift: X <<= count - */ -int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ) -{ - int ret; - size_t i, v0, t1; - mbedtls_mpi_uint r0 = 0, r1; - MPI_VALIDATE_RET( X != NULL ); - - v0 = count / (biL ); - t1 = count & (biL - 1); - - i = mbedtls_mpi_bitlen( X ) + count; - - if( X->n * biL < i ) - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) ); - - ret = 0; - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = X->n; i > v0; i-- ) - X->p[i - 1] = X->p[i - v0 - 1]; - - for( ; i > 0; i-- ) - X->p[i - 1] = 0; - } - - /* - * shift by count % limb_size - */ - if( t1 > 0 ) - { - for( i = v0; i < X->n; i++ ) - { - r1 = X->p[i] >> (biL - t1); - X->p[i] <<= t1; - X->p[i] |= r0; - r0 = r1; - } - } - -cleanup: - - return( ret ); -} - -/* - * Right-shift: X >>= count - */ -int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) -{ - size_t i, v0, v1; - mbedtls_mpi_uint r0 = 0, r1; - MPI_VALIDATE_RET( X != NULL ); - - v0 = count / biL; - v1 = count & (biL - 1); - - if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) - return mbedtls_mpi_lset( X, 0 ); - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = 0; i < X->n - v0; i++ ) - X->p[i] = X->p[i + v0]; - - for( ; i < X->n; i++ ) - X->p[i] = 0; - } - - /* - * shift by count % limb_size - */ - if( v1 > 0 ) - { - for( i = X->n; i > 0; i-- ) - { - r1 = X->p[i - 1] << (biL - v1); - X->p[i - 1] >>= v1; - X->p[i - 1] |= r0; - r0 = r1; - } - } - - return( 0 ); -} - -/* - * Compare unsigned values - */ -int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ) -{ - size_t i, j; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - for( i = X->n; i > 0; i-- ) - if( X->p[i - 1] != 0 ) - break; - - for( j = Y->n; j > 0; j-- ) - if( Y->p[j - 1] != 0 ) - break; - - if( i == 0 && j == 0 ) - return( 0 ); - - if( i > j ) return( 1 ); - if( j > i ) return( -1 ); - - for( ; i > 0; i-- ) - { - if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); - if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ) -{ - size_t i, j; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - for( i = X->n; i > 0; i-- ) - if( X->p[i - 1] != 0 ) - break; - - for( j = Y->n; j > 0; j-- ) - if( Y->p[j - 1] != 0 ) - break; - - if( i == 0 && j == 0 ) - return( 0 ); - - if( i > j ) return( X->s ); - if( j > i ) return( -Y->s ); - - if( X->s > 0 && Y->s < 0 ) return( 1 ); - if( Y->s > 0 && X->s < 0 ) return( -1 ); - - for( ; i > 0; i-- ) - { - if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); - if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ) -{ - mbedtls_mpi Y; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - - *p = ( z < 0 ) ? -z : z; - Y.s = ( z < 0 ) ? -1 : 1; - Y.n = 1; - Y.p = p; - - return( mbedtls_mpi_cmp_mpi( X, &Y ) ); -} - -/* - * Unsigned addition: X = |A| + |B| (HAC 14.7) - */ -int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - size_t i, j; - mbedtls_mpi_uint *o, *p, c, tmp; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - if( X == B ) - { - const mbedtls_mpi *T = A; A = X; B = T; - } - - if( X != A ) - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); - - /* - * X should always be positive as a result of unsigned additions. - */ - X->s = 1; - - for( j = B->n; j > 0; j-- ) - if( B->p[j - 1] != 0 ) - break; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); - - o = B->p; p = X->p; c = 0; - - /* - * tmp is used because it might happen that p == o - */ - for( i = 0; i < j; i++, o++, p++ ) - { - tmp= *o; - *p += c; c = ( *p < c ); - *p += tmp; c += ( *p < tmp ); - } - - while( c != 0 ) - { - if( i >= X->n ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) ); - p = X->p + i; - } - - *p += c; c = ( *p < c ); i++; p++; - } - -cleanup: - - return( ret ); -} - -/* - * Helper for mbedtls_mpi subtraction - */ -static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d ) -{ - size_t i; - mbedtls_mpi_uint c, z; - - for( i = c = 0; i < n; i++, s++, d++ ) - { - z = ( *d < c ); *d -= c; - c = ( *d < *s ) + z; *d -= *s; - } - - while( c != 0 ) - { - z = ( *d < c ); *d -= c; - c = z; d++; - } -} - -/* - * Unsigned subtraction: X = |A| - |B| (HAC 14.9) - */ -int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - mbedtls_mpi TB; - int ret; - size_t n; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) - return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); - - mbedtls_mpi_init( &TB ); - - if( X == B ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); - B = &TB; - } - - if( X != A ) - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); - - /* - * X should always be positive as a result of unsigned subtractions. - */ - X->s = 1; - - ret = 0; - - for( n = B->n; n > 0; n-- ) - if( B->p[n - 1] != 0 ) - break; - - mpi_sub_hlp( n, B->p, X->p ); - -cleanup: - - mbedtls_mpi_free( &TB ); - - return( ret ); -} - -/* - * Signed addition: X = A + B - */ -int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret, s; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - s = A->s; - if( A->s * B->s < 0 ) - { - if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed subtraction: X = A - B - */ -int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret, s; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - s = A->s; - if( A->s * B->s > 0 ) - { - if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed addition: X = A + b - */ -int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mbedtls_mpi_add_mpi( X, A, &_B ) ); -} - -/* - * Signed subtraction: X = A - b - */ -int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mbedtls_mpi_sub_mpi( X, A, &_B ) ); -} - -/* - * Helper for mbedtls_mpi multiplication - */ -static -#if defined(__APPLE__) && defined(__arm__) -/* - * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) - * appears to need this to prevent bad ARM code generation at -O3. - */ -__attribute__ ((noinline)) -#endif -void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b ) -{ - mbedtls_mpi_uint c = 0, t = 0; - -#if defined(MULADDC_HUIT) - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_HUIT - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#else /* MULADDC_HUIT */ - for( ; i >= 16; i -= 16 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#endif /* MULADDC_HUIT */ - - t++; - - do { - *d += c; c = ( *d < c ); d++; - } - while( c != 0 ); -} - -/* - * Baseline multiplication: X = A * B (HAC 14.12) - */ -int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - size_t i, j; - mbedtls_mpi TA, TB; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); - - if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; } - if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; } - - for( i = A->n; i > 0; i-- ) - if( A->p[i - 1] != 0 ) - break; - - for( j = B->n; j > 0; j-- ) - if( B->p[j - 1] != 0 ) - break; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - for( ; j > 0; j-- ) - mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] ); - - X->s = A->s * B->s; - -cleanup: - - mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA ); - - return( ret ); -} - -/* - * Baseline multiplication: X = A * b - */ -int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - _B.s = 1; - _B.n = 1; - _B.p = p; - p[0] = b; - - return( mbedtls_mpi_mul_mpi( X, A, &_B ) ); -} - -/* - * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and - * mbedtls_mpi_uint divisor, d - */ -static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1, - mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r ) -{ -#if defined(MBEDTLS_HAVE_UDBL) - mbedtls_t_udbl dividend, quotient; -#else - const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH; - const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1; - mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient; - mbedtls_mpi_uint u0_msw, u0_lsw; - size_t s; -#endif - - /* - * Check for overflow - */ - if( 0 == d || u1 >= d ) - { - if (r != NULL) *r = ~0; - - return ( ~0 ); - } - -#if defined(MBEDTLS_HAVE_UDBL) - dividend = (mbedtls_t_udbl) u1 << biL; - dividend |= (mbedtls_t_udbl) u0; - quotient = dividend / d; - if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 ) - quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1; - - if( r != NULL ) - *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) ); - - return (mbedtls_mpi_uint) quotient; -#else - - /* - * Algorithm D, Section 4.3.1 - The Art of Computer Programming - * Vol. 2 - Seminumerical Algorithms, Knuth - */ - - /* - * Normalize the divisor, d, and dividend, u0, u1 - */ - s = mbedtls_clz( d ); - d = d << s; - - u1 = u1 << s; - u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) ); - u0 = u0 << s; - - d1 = d >> biH; - d0 = d & uint_halfword_mask; - - u0_msw = u0 >> biH; - u0_lsw = u0 & uint_halfword_mask; - - /* - * Find the first quotient and remainder - */ - q1 = u1 / d1; - r0 = u1 - d1 * q1; - - while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) ) - { - q1 -= 1; - r0 += d1; - - if ( r0 >= radix ) break; - } - - rAX = ( u1 * radix ) + ( u0_msw - q1 * d ); - q0 = rAX / d1; - r0 = rAX - q0 * d1; - - while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) ) - { - q0 -= 1; - r0 += d1; - - if ( r0 >= radix ) break; - } - - if (r != NULL) - *r = ( rAX * radix + u0_lsw - q0 * d ) >> s; - - quotient = q1 * radix + q0; - - return quotient; -#endif -} - -/* - * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) - */ -int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B ) -{ - int ret; - size_t i, n, t, k; - mbedtls_mpi X, Y, Z, T1, T2; - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - if( mbedtls_mpi_cmp_int( B, 0 ) == 0 ) - return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); - - mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); - mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); - - if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) - { - if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) ); - if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) ); - return( 0 ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) ); - X.s = Y.s = 1; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) ); - - k = mbedtls_mpi_bitlen( &Y ) % biL; - if( k < biL - 1 ) - { - k = biL - 1 - k; - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) ); - } - else k = 0; - - n = X.n - 1; - t = Y.n - 1; - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) ); - - while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 ) - { - Z.p[n - t]++; - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) ); - } - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) ); - - for( i = n; i > t ; i-- ) - { - if( X.p[i] >= Y.p[t] ) - Z.p[i - t - 1] = ~0; - else - { - Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1], - Y.p[t], NULL); - } - - Z.p[i - t - 1]++; - do - { - Z.p[i - t - 1]--; - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) ); - T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1]; - T1.p[1] = Y.p[t]; - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) ); - T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2]; - T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1]; - T2.p[2] = X.p[i]; - } - while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); - - if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) ); - Z.p[i - t - 1]--; - } - } - - if( Q != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) ); - Q->s = A->s * B->s; - } - - if( R != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) ); - X.s = A->s; - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) ); - - if( mbedtls_mpi_cmp_int( R, 0 ) == 0 ) - R->s = 1; - } - -cleanup: - - mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); - mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); - - return( ret ); -} - -/* - * Division by int: A = Q * b + R - */ -int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, - const mbedtls_mpi *A, - mbedtls_mpi_sint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( A != NULL ); - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) ); -} - -/* - * Modulo: R = A mod B - */ -int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - MPI_VALIDATE_RET( R != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - if( mbedtls_mpi_cmp_int( B, 0 ) < 0 ) - return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) ); - - while( mbedtls_mpi_cmp_int( R, 0 ) < 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); - - while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); - -cleanup: - - return( ret ); -} - -/* - * Modulo: r = A mod b - */ -int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b ) -{ - size_t i; - mbedtls_mpi_uint x, y, z; - MPI_VALIDATE_RET( r != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - if( b == 0 ) - return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); - - if( b < 0 ) - return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); - - /* - * handle trivial cases - */ - if( b == 1 ) - { - *r = 0; - return( 0 ); - } - - if( b == 2 ) - { - *r = A->p[0] & 1; - return( 0 ); - } - - /* - * general case - */ - for( i = A->n, y = 0; i > 0; i-- ) - { - x = A->p[i - 1]; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - - x <<= biH; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - } - - /* - * If A is negative, then the current y represents a negative value. - * Flipping it to the positive side. - */ - if( A->s < 0 && y != 0 ) - y = b - y; - - *r = y; - - return( 0 ); -} - -/* - * Fast Montgomery initialization (thanks to Tom St Denis) - */ -static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N ) -{ - mbedtls_mpi_uint x, m0 = N->p[0]; - unsigned int i; - - x = m0; - x += ( ( m0 + 2 ) & 4 ) << 1; - - for( i = biL; i >= 8; i /= 2 ) - x *= ( 2 - ( m0 * x ) ); - - *mm = ~x + 1; -} - -/* - * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) - */ -static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm, - const mbedtls_mpi *T ) -{ - size_t i, n, m; - mbedtls_mpi_uint u0, u1, *d; - - if( T->n < N->n + 1 || T->p == NULL ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - memset( T->p, 0, T->n * ciL ); - - d = T->p; - n = N->n; - m = ( B->n < n ) ? B->n : n; - - for( i = 0; i < n; i++ ) - { - /* - * T = (T + u0*B + u1*N) / 2^biL - */ - u0 = A->p[i]; - u1 = ( d[0] + u0 * B->p[0] ) * mm; - - mpi_mul_hlp( m, B->p, d, u0 ); - mpi_mul_hlp( n, N->p, d, u1 ); - - *d++ = u0; d[n + 1] = 0; - } - - memcpy( A->p, d, ( n + 1 ) * ciL ); - - if( mbedtls_mpi_cmp_abs( A, N ) >= 0 ) - mpi_sub_hlp( n, N->p, A->p ); - else - /* prevent timing attacks */ - mpi_sub_hlp( n, A->p, T->p ); - - return( 0 ); -} - -/* - * Montgomery reduction: A = A * R^-1 mod N - */ -static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, - mbedtls_mpi_uint mm, const mbedtls_mpi *T ) -{ - mbedtls_mpi_uint z = 1; - mbedtls_mpi U; - - U.n = U.s = (int) z; - U.p = &z; - - return( mpi_montmul( A, &U, N, mm, T ) ); -} - -/* - * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) - */ -int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *_RR ) -{ - int ret; - size_t wbits, wsize, one = 1; - size_t i, j, nblimbs; - size_t bufsize, nbits; - mbedtls_mpi_uint ei, mm, state; - mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; - int neg; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( E != NULL ); - MPI_VALIDATE_RET( N != NULL ); - - if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - /* - * Init temps and window size - */ - mpi_montg_init( &mm, N ); - mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T ); - mbedtls_mpi_init( &Apos ); - memset( W, 0, sizeof( W ) ); - - i = mbedtls_mpi_bitlen( E ); - - wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : - ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; - -#if( MBEDTLS_MPI_WINDOW_SIZE < 6 ) - if( wsize > MBEDTLS_MPI_WINDOW_SIZE ) - wsize = MBEDTLS_MPI_WINDOW_SIZE; -#endif - - j = N->n + 1; - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) ); - - /* - * Compensate for negative A (and correct at the end) - */ - neg = ( A->s == -1 ); - if( neg ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) ); - Apos.s = 1; - A = &Apos; - } - - /* - * If 1st call, pre-compute R^2 mod N - */ - if( _RR == NULL || _RR->p == NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) ); - - if( _RR != NULL ) - memcpy( _RR, &RR, sizeof( mbedtls_mpi ) ); - } - else - memcpy( &RR, _RR, sizeof( mbedtls_mpi ) ); - - /* - * W[1] = A * R^2 * R^-1 mod N = A * R mod N - */ - if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) ); - else - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) ); - - MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) ); - - /* - * X = R^2 * R^-1 mod N = R mod N - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) ); - MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); - - if( wsize > 1 ) - { - /* - * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) - */ - j = one << ( wsize - 1 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) ); - - for( i = 0; i < wsize - 1; i++ ) - MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) ); - - /* - * W[i] = W[i - 1] * W[1] - */ - for( i = j + 1; i < ( one << wsize ); i++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) ); - - MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) ); - } - } - - nblimbs = E->n; - bufsize = 0; - nbits = 0; - wbits = 0; - state = 0; - - while( 1 ) - { - if( bufsize == 0 ) - { - if( nblimbs == 0 ) - break; - - nblimbs--; - - bufsize = sizeof( mbedtls_mpi_uint ) << 3; - } - - bufsize--; - - ei = (E->p[nblimbs] >> bufsize) & 1; - - /* - * skip leading 0s - */ - if( ei == 0 && state == 0 ) - continue; - - if( ei == 0 && state == 1 ) - { - /* - * out of window, square X - */ - MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); - continue; - } - - /* - * add ei to current window - */ - state = 2; - - nbits++; - wbits |= ( ei << ( wsize - nbits ) ); - - if( nbits == wsize ) - { - /* - * X = X^wsize R^-1 mod N - */ - for( i = 0; i < wsize; i++ ) - MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); - - /* - * X = X * W[wbits] R^-1 mod N - */ - MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) ); - - state--; - nbits = 0; - wbits = 0; - } - } - - /* - * process the remaining bits - */ - for( i = 0; i < nbits; i++ ) - { - MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); - - wbits <<= 1; - - if( ( wbits & ( one << wsize ) ) != 0 ) - MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) ); - } - - /* - * X = A^E * R * R^-1 mod N = A^E mod N - */ - MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); - - if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 ) - { - X->s = -1; - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) ); - } - -cleanup: - - for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) - mbedtls_mpi_free( &W[i] ); - - mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos ); - - if( _RR == NULL || _RR->p == NULL ) - mbedtls_mpi_free( &RR ); - - return( ret ); -} - -/* - * Greatest common divisor: G = gcd(A, B) (HAC 14.54) - */ -int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - size_t lz, lzt; - mbedtls_mpi TG, TA, TB; - - MPI_VALIDATE_RET( G != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); - - lz = mbedtls_mpi_lsb( &TA ); - lzt = mbedtls_mpi_lsb( &TB ); - - if( lzt < lz ) - lz = lzt; - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) ); - - TA.s = TB.s = 1; - - while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) ); - - if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) ); - } - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) ); - -cleanup: - - mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB ); - - return( ret ); -} - -/* - * Fill X with size bytes of random. - * - * Use a temporary bytes representation to make sure the result is the same - * regardless of the platform endianness (useful when f_rng is actually - * deterministic, eg for tests). - */ -int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t const limbs = CHARS_TO_LIMBS( size ); - size_t const overhead = ( limbs * ciL ) - size; - unsigned char *Xp; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - if( X->n != limbs ) - { - mbedtls_mpi_free( X ); - mbedtls_mpi_init( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); - } - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - Xp = (unsigned char*) X->p; - f_rng( p_rng, Xp + overhead, size ); - - mpi_bigendian_to_host( X->p, limbs ); - -cleanup: - return( ret ); -} - -/* - * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) - */ -int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ) -{ - int ret; - mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( N != NULL ); - - if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 ); - mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV ); - mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) ); - - if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) - { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) ); - - do - { - while( ( TU.p[0] & 1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) ); - - if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) ); - } - - while( ( TV.p[0] & 1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) ); - - if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) ); - } - - if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) ); - } - } - while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 ); - - while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) ); - - while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) ); - -cleanup: - - mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 ); - mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV ); - mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 ); - - return( ret ); -} - -#if defined(MBEDTLS_GENPRIME) - -static const int small_prime[] = -{ - 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, - 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, - 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, - 271, 277, 281, 283, 293, 307, 311, 313, - 317, 331, 337, 347, 349, 353, 359, 367, - 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, - 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, - 577, 587, 593, 599, 601, 607, 613, 617, - 619, 631, 641, 643, 647, 653, 659, 661, - 673, 677, 683, 691, 701, 709, 719, 727, - 733, 739, 743, 751, 757, 761, 769, 773, - 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, - 887, 907, 911, 919, 929, 937, 941, 947, - 953, 967, 971, 977, 983, 991, 997, -103 -}; - -/* - * Small divisors test (X must be positive) - * - * Return values: - * 0: no small factor (possible prime, more tests needed) - * 1: certain prime - * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime - * other negative: error - */ -static int mpi_check_small_factors( const mbedtls_mpi *X ) -{ - int ret = 0; - size_t i; - mbedtls_mpi_uint r; - - if( ( X->p[0] & 1 ) == 0 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - - for( i = 0; small_prime[i] > 0; i++ ) - { - if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 ) - return( 1 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) ); - - if( r == 0 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - } - -cleanup: - return( ret ); -} - -/* - * Miller-Rabin pseudo-primality test (HAC 4.24) - */ -static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret, count; - size_t i, j, k, s; - mbedtls_mpi W, R, T, A, RR; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); - mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A ); - mbedtls_mpi_init( &RR ); - - /* - * W = |X| - 1 - * R = W >> lsb( W ) - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) ); - s = mbedtls_mpi_lsb( &W ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) ); - - i = mbedtls_mpi_bitlen( X ); - - for( i = 0; i < rounds; i++ ) - { - /* - * pick a random A, 1 < A < |X| - 1 - */ - count = 0; - do { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); - - j = mbedtls_mpi_bitlen( &A ); - k = mbedtls_mpi_bitlen( &W ); - if (j > k) { - A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1; - } - - if (count++ > 30) { - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - } - - } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 || - mbedtls_mpi_cmp_int( &A, 1 ) <= 0 ); - - /* - * A = A^R mod |X| - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) ); - - if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 || - mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) - continue; - - j = 1; - while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ) - { - /* - * A = A * A mod |X| - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) ); - - if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) - break; - - j++; - } - - /* - * not prime if A != |X| - 1 or A == 1 - */ - if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 || - mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) - { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - break; - } - } - -cleanup: - mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); - mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A ); - mbedtls_mpi_free( &RR ); - - return( ret ); -} - -/* - * Pseudo-primality test: small factors, then Miller-Rabin - */ -int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_mpi XX; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - XX.s = 1; - XX.n = X->n; - XX.p = X->p; - - if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 || - mbedtls_mpi_cmp_int( &XX, 1 ) == 0 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - - if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 ) - return( 0 ); - - if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) - { - if( ret == 1 ) - return( 0 ); - - return( ret ); - } - - return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/* - * Pseudo-primality test, error probability 2^-80 - */ -int mbedtls_mpi_is_prime( const mbedtls_mpi *X, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - /* - * In the past our key generation aimed for an error rate of at most - * 2^-80. Since this function is deprecated, aim for the same certainty - * here as well. - */ - return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) ); -} -#endif - -/* - * Prime number generation - * - * To generate an RSA key in a way recommended by FIPS 186-4, both primes must - * be either 1024 bits or 1536 bits long, and flags must contain - * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR. - */ -int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ -#ifdef MBEDTLS_HAVE_INT64 -// ceil(2^63.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL -#else -// ceil(2^31.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U -#endif - int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - size_t k, n; - int rounds; - mbedtls_mpi_uint r; - mbedtls_mpi Y; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &Y ); - - n = BITS_TO_LIMBS( nbits ); - - if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 ) - { - /* - * 2^-80 error probability, number of rounds chosen per HAC, table 4.4 - */ - rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 : - ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 : - ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 ); - } - else - { - /* - * 2^-100 error probability, number of rounds computed based on HAC, - * fact 4.48 - */ - rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 : - ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 : - ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 : - ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 ); - } - - while( 1 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); - /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */ - if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue; - - k = n * biL; - if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) ); - X->p[0] |= 1; - - if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 ) - { - ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng ); - - if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - } - else - { - /* - * An necessary condition for Y and X = 2Y + 1 to be prime - * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). - * Make sure it is satisfied, while keeping X = 3 mod 4 - */ - - X->p[0] |= 2; - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) ); - if( r == 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) ); - else if( r == 1 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) ); - - /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) ); - - while( 1 ) - { - /* - * First, check small factors for X and Y - * before doing Miller-Rabin on any of them - */ - if( ( ret = mpi_check_small_factors( X ) ) == 0 && - ( ret = mpi_check_small_factors( &Y ) ) == 0 && - ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) ) - == 0 && - ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) ) - == 0 ) - goto cleanup; - - if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - /* - * Next candidates. We want to preserve Y = (X-1) / 2 and - * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) - * so up Y by 6 and X by 12. - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) ); - } - } - } - -cleanup: - - mbedtls_mpi_free( &Y ); - - return( ret ); -} - -#endif /* MBEDTLS_GENPRIME */ - -#if defined(MBEDTLS_SELF_TEST) - -#define GCD_PAIR_COUNT 3 - -static const int gcd_pairs[GCD_PAIR_COUNT][3] = -{ - { 693, 609, 21 }, - { 1764, 868, 28 }, - { 768454923, 542167814, 1 } -}; - -/* - * Checkup routine - */ -int mbedtls_mpi_self_test( int verbose ) -{ - int ret, i; - mbedtls_mpi A, E, N, X, Y, U, V; - - mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X ); - mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16, - "EFE021C2645FD1DC586E69184AF4A31E" \ - "D5F53E93B5F123FA41680867BA110131" \ - "944FE7952E2517337780CB0DB80E61AA" \ - "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16, - "B2E7EFD37075B9F03FF989C7C5051C20" \ - "34D2A323810251127E7BF8625A4F49A5" \ - "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ - "5B5C25763222FEFCCFC38B832366C29E" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16, - "0066A198186C18C10B2F5ED9B522752A" \ - "9830B69916E535C8F047518A889A43A5" \ - "94B6BED27A168D31D4A52F88925AA8F5" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "602AB7ECA597A3D6B56FF9829A5E8B85" \ - "9E857EA95A03512E2BAE7391688D264A" \ - "A5663B0341DB9CCFD2C4C5F421FEC814" \ - "8001B72E848A38CAE1C65F78E56ABDEF" \ - "E12D3C039B8A02D6BE593F0BBBDA56F1" \ - "ECF677152EF804370C1A305CAF3B5BF1" \ - "30879B56C61DE584A0F53A2447A51E" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #1 (mul_mpi): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "256567336059E52CAE22925474705F39A94" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16, - "6613F26162223DF488E9CD48CC132C7A" \ - "0AC93C701B001B092E4E5B9F73BCD27B" \ - "9EE50D0657C77F374E903CDFA4C642" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #2 (div_mpi): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 || - mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "36E139AEA55215609D2816998ED020BB" \ - "BD96C37890F65171D948E9BC7CBAA4D9" \ - "325D24D6A3C12710F10A09FA08AB87" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #3 (exp_mod): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ - "C3DBA76456363A10869622EAC2DD84EC" \ - "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #4 (inv_mod): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #5 (simple gcd): " ); - - for( i = 0; i < GCD_PAIR_COUNT; i++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) ); - - if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed at %d\n", i ); - - ret = 1; - goto cleanup; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -cleanup: - - if( ret != 0 && verbose != 0 ) - mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); - - mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X ); - mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_BIGNUM_C */ diff --git a/library/blowfish.c b/library/blowfish.c deleted file mode 100644 index cbf9238246..0000000000 --- a/library/blowfish.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * Blowfish implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The Blowfish block cipher was designed by Bruce Schneier in 1993. - * http://www.schneier.com/blowfish.html - * http://en.wikipedia.org/wiki/Blowfish_%28cipher%29 - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_BLOWFISH_C) - -#include "mbedtls/blowfish.h" -#include "mbedtls/platform_util.h" - -#include - -#if !defined(MBEDTLS_BLOWFISH_ALT) - -/* Parameter validation macros */ -#define BLOWFISH_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ) -#define BLOWFISH_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = { - 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, - 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, - 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, - 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, - 0x9216D5D9L, 0x8979FB1BL -}; - -/* declarations of data at the end of this file */ -static const uint32_t S[4][256]; - -static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x ) -{ - unsigned short a, b, c, d; - uint32_t y; - - d = (unsigned short)(x & 0xFF); - x >>= 8; - c = (unsigned short)(x & 0xFF); - x >>= 8; - b = (unsigned short)(x & 0xFF); - x >>= 8; - a = (unsigned short)(x & 0xFF); - y = ctx->S[0][a] + ctx->S[1][b]; - y = y ^ ctx->S[2][c]; - y = y + ctx->S[3][d]; - - return( y ); -} - -static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) -{ - uint32_t Xl, Xr, temp; - short i; - - Xl = *xl; - Xr = *xr; - - for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i ) - { - Xl = Xl ^ ctx->P[i]; - Xr = F( ctx, Xl ) ^ Xr; - - temp = Xl; - Xl = Xr; - Xr = temp; - } - - temp = Xl; - Xl = Xr; - Xr = temp; - - Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS]; - Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1]; - - *xl = Xl; - *xr = Xr; -} - -static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) -{ - uint32_t Xl, Xr, temp; - short i; - - Xl = *xl; - Xr = *xr; - - for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i ) - { - Xl = Xl ^ ctx->P[i]; - Xr = F( ctx, Xl ) ^ Xr; - - temp = Xl; - Xl = Xr; - Xr = temp; - } - - temp = Xl; - Xl = Xr; - Xr = temp; - - Xr = Xr ^ ctx->P[1]; - Xl = Xl ^ ctx->P[0]; - - *xl = Xl; - *xr = Xr; -} - -void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ) -{ - BLOWFISH_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_blowfish_context ) ); -} - -void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) ); -} - -/* - * Blowfish key schedule - */ -int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, - const unsigned char *key, - unsigned int keybits ) -{ - unsigned int i, j, k; - uint32_t data, datal, datar; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( key != NULL ); - - if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || - keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS || - keybits % 8 != 0 ) - { - return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); - } - - keybits >>= 3; - - for( i = 0; i < 4; i++ ) - { - for( j = 0; j < 256; j++ ) - ctx->S[i][j] = S[i][j]; - } - - j = 0; - for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i ) - { - data = 0x00000000; - for( k = 0; k < 4; ++k ) - { - data = ( data << 8 ) | key[j++]; - if( j >= keybits ) - j = 0; - } - ctx->P[i] = P[i] ^ data; - } - - datal = 0x00000000; - datar = 0x00000000; - - for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 ) - { - blowfish_enc( ctx, &datal, &datar ); - ctx->P[i] = datal; - ctx->P[i + 1] = datar; - } - - for( i = 0; i < 4; i++ ) - { - for( j = 0; j < 256; j += 2 ) - { - blowfish_enc( ctx, &datal, &datar ); - ctx->S[i][j] = datal; - ctx->S[i][j + 1] = datar; - } - } - return( 0 ); -} - -/* - * Blowfish-ECB block encryption/decryption - */ -int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, - int mode, - const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], - unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] ) -{ - uint32_t X0, X1; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || - mode == MBEDTLS_BLOWFISH_DECRYPT ); - BLOWFISH_VALIDATE_RET( input != NULL ); - BLOWFISH_VALIDATE_RET( output != NULL ); - - GET_UINT32_BE( X0, input, 0 ); - GET_UINT32_BE( X1, input, 4 ); - - if( mode == MBEDTLS_BLOWFISH_DECRYPT ) - { - blowfish_dec( ctx, &X0, &X1 ); - } - else /* MBEDTLS_BLOWFISH_ENCRYPT */ - { - blowfish_enc( ctx, &X0, &X1 ); - } - - PUT_UINT32_BE( X0, output, 0 ); - PUT_UINT32_BE( X1, output, 4 ); - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * Blowfish-CBC buffer encryption/decryption - */ -int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE]; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || - mode == MBEDTLS_BLOWFISH_DECRYPT ); - BLOWFISH_VALIDATE_RET( iv != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); - - if( length % MBEDTLS_BLOWFISH_BLOCKSIZE ) - return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_BLOWFISH_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE ); - mbedtls_blowfish_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE ); - - input += MBEDTLS_BLOWFISH_BLOCKSIZE; - output += MBEDTLS_BLOWFISH_BLOCKSIZE; - length -= MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_blowfish_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE ); - - input += MBEDTLS_BLOWFISH_BLOCKSIZE; - output += MBEDTLS_BLOWFISH_BLOCKSIZE; - length -= MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * Blowfish CFB buffer encryption/decryption - */ -int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n; - - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || - mode == MBEDTLS_BLOWFISH_DECRYPT ); - BLOWFISH_VALIDATE_RET( iv != NULL ); - BLOWFISH_VALIDATE_RET( iv_off != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); - - n = *iv_off; - if( n >= 8 ) - return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_BLOWFISH_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Blowfish CTR buffer encryption/decryption - */ -int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( nonce_counter != NULL ); - BLOWFISH_VALIDATE_RET( stream_block != NULL ); - BLOWFISH_VALIDATE_RET( nc_off != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); - - n = *nc_off; - if( n >= 8 ) - return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter, - stream_block ); - - for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static const uint32_t S[4][256] = { - { 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, - 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, - 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, - 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, - 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, - 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, - 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, - 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, - 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, - 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, - 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, - 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, - 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, - 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, - 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, - 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, - 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, - 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, - 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, - 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, - 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, - 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, - 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, - 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, - 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, - 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, - 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, - 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, - 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, - 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, - 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, - 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, - 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, - 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, - 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, - 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, - 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, - 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, - 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, - 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, - 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, - 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, - 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, - 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, - 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, - 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, - 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, - 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, - 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, - 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, - 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, - 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, - 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, - 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, - 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, - 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, - 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, - 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, - 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, - 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, - 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, - 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, - 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, - 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL }, - { 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, - 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, - 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, - 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, - 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, - 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, - 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, - 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, - 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, - 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, - 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, - 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, - 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, - 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, - 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, - 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, - 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, - 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, - 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, - 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, - 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, - 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, - 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, - 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, - 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, - 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, - 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, - 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, - 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, - 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, - 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, - 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, - 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, - 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, - 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, - 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, - 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, - 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, - 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, - 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, - 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, - 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, - 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, - 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, - 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, - 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, - 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, - 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, - 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, - 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, - 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, - 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, - 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, - 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, - 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, - 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, - 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, - 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, - 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, - 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, - 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, - 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, - 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, - 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L }, - { 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, - 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, - 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, - 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, - 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, - 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, - 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, - 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, - 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, - 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, - 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, - 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, - 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, - 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, - 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, - 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, - 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, - 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, - 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, - 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, - 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, - 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, - 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, - 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, - 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, - 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, - 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, - 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, - 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, - 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, - 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, - 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, - 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, - 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, - 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, - 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, - 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, - 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, - 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, - 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, - 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, - 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, - 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, - 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, - 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, - 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, - 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, - 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, - 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, - 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, - 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, - 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, - 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, - 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, - 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, - 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, - 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, - 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, - 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, - 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, - 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, - 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, - 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, - 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L }, - { 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, - 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, - 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, - 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, - 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, - 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, - 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, - 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, - 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, - 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, - 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, - 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, - 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, - 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, - 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, - 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, - 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, - 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, - 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, - 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, - 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, - 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, - 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, - 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, - 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, - 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, - 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, - 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, - 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, - 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, - 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, - 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, - 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, - 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, - 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, - 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, - 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, - 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, - 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, - 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, - 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, - 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, - 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, - 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, - 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, - 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, - 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, - 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, - 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, - 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, - 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, - 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, - 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, - 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, - 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, - 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, - 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, - 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, - 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, - 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, - 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, - 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, - 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, - 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L } -}; - -#endif /* !MBEDTLS_BLOWFISH_ALT */ -#endif /* MBEDTLS_BLOWFISH_C */ diff --git a/library/camellia.c b/library/camellia.c deleted file mode 100644 index 22262b89a8..0000000000 --- a/library/camellia.c +++ /dev/null @@ -1,1114 +0,0 @@ -/* - * Camellia implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The Camellia block cipher was designed by NTT and Mitsubishi Electric - * Corporation. - * - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CAMELLIA_C) - -#include "mbedtls/camellia.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_CAMELLIA_ALT) - -/* Parameter validation macros */ -#define CAMELLIA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ) -#define CAMELLIA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -static const unsigned char SIGMA_CHARS[6][8] = -{ - { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b }, - { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 }, - { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe }, - { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c }, - { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d }, - { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd } -}; - -#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) - -static const unsigned char FSb[256] = -{ - 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, - 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, - 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, - 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, - 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, - 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, - 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, - 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, - 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, - 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, - 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, - 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, - 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, - 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, - 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, - 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158 -}; - -#define SBOX1(n) FSb[(n)] -#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff) -#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff) -#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff] - -#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ - -static const unsigned char FSb[256] = -{ - 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, - 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, - 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, - 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, - 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, - 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, - 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, - 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, - 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, - 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, - 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, - 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, - 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, - 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, - 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, - 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 -}; - -static const unsigned char FSb2[256] = -{ - 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, - 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, - 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, - 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, - 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, - 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, - 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, - 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, - 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, - 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, - 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, - 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, - 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, - 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, - 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, - 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 -}; - -static const unsigned char FSb3[256] = -{ - 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, - 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, - 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, - 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, - 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, - 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, - 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, - 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, - 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, - 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, - 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, - 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, - 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, - 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, - 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, - 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 -}; - -static const unsigned char FSb4[256] = -{ - 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, - 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, - 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, - 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, - 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, - 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, - 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, - 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, - 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, - 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, - 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, - 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, - 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, - 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, - 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, - 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 -}; - -#define SBOX1(n) FSb[(n)] -#define SBOX2(n) FSb2[(n)] -#define SBOX3(n) FSb3[(n)] -#define SBOX4(n) FSb4[(n)] - -#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ - -static const unsigned char shifts[2][4][4] = -{ - { - { 1, 1, 1, 1 }, /* KL */ - { 0, 0, 0, 0 }, /* KR */ - { 1, 1, 1, 1 }, /* KA */ - { 0, 0, 0, 0 } /* KB */ - }, - { - { 1, 0, 1, 1 }, /* KL */ - { 1, 1, 0, 1 }, /* KR */ - { 1, 1, 1, 0 }, /* KA */ - { 1, 1, 0, 1 } /* KB */ - } -}; - -static const signed char indexes[2][4][20] = -{ - { - { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39, - 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */ - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */ - { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, - 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */ - }, - { - { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1, - -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */ - { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, - 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */ - { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, - 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */ - { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, - 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */ - } -}; - -static const signed char transposes[2][20] = -{ - { - 21, 22, 23, 20, - -1, -1, -1, -1, - 18, 19, 16, 17, - 11, 8, 9, 10, - 15, 12, 13, 14 - }, - { - 25, 26, 27, 24, - 29, 30, 31, 28, - 18, 19, 16, 17, - -1, -1, -1, -1, - -1, -1, -1, -1 - } -}; - -/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */ -#define ROTL(DEST, SRC, SHIFT) \ -{ \ - (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \ - (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \ - (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \ - (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \ -} - -#define FL(XL, XR, KL, KR) \ -{ \ - (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \ - (XL) = ((XR) | (KR)) ^ (XL); \ -} - -#define FLInv(YL, YR, KL, KR) \ -{ \ - (YL) = ((YR) | (KR)) ^ (YL); \ - (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \ -} - -#define SHIFT_AND_PLACE(INDEX, OFFSET) \ -{ \ - TK[0] = KC[(OFFSET) * 4 + 0]; \ - TK[1] = KC[(OFFSET) * 4 + 1]; \ - TK[2] = KC[(OFFSET) * 4 + 2]; \ - TK[3] = KC[(OFFSET) * 4 + 3]; \ - \ - for( i = 1; i <= 4; i++ ) \ - if( shifts[(INDEX)][(OFFSET)][i -1] ) \ - ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \ - \ - for( i = 0; i < 20; i++ ) \ - if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \ - RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \ - } \ -} - -static void camellia_feistel( const uint32_t x[2], const uint32_t k[2], - uint32_t z[2]) -{ - uint32_t I0, I1; - I0 = x[0] ^ k[0]; - I1 = x[1] ^ k[1]; - - I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) | - ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) | - ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) | - ((uint32_t) SBOX4((I0 ) & 0xFF) ); - I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) | - ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) | - ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) | - ((uint32_t) SBOX1((I1 ) & 0xFF) ); - - I0 ^= (I1 << 8) | (I1 >> 24); - I1 ^= (I0 << 16) | (I0 >> 16); - I0 ^= (I1 >> 8) | (I1 << 24); - I1 ^= (I0 >> 8) | (I0 << 24); - - z[0] ^= I1; - z[1] ^= I0; -} - -void mbedtls_camellia_init( mbedtls_camellia_context *ctx ) -{ - CAMELLIA_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_camellia_context ) ); -} - -void mbedtls_camellia_free( mbedtls_camellia_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_camellia_context ) ); -} - -/* - * Camellia key schedule (encryption) - */ -int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ) -{ - int idx; - size_t i; - uint32_t *RK; - unsigned char t[64]; - uint32_t SIGMA[6][2]; - uint32_t KC[16]; - uint32_t TK[20]; - - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( key != NULL ); - - RK = ctx->rk; - - memset( t, 0, 64 ); - memset( RK, 0, sizeof(ctx->rk) ); - - switch( keybits ) - { - case 128: ctx->nr = 3; idx = 0; break; - case 192: - case 256: ctx->nr = 4; idx = 1; break; - default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); - } - - for( i = 0; i < keybits / 8; ++i ) - t[i] = key[i]; - - if( keybits == 192 ) { - for( i = 0; i < 8; i++ ) - t[24 + i] = ~t[16 + i]; - } - - /* - * Prepare SIGMA values - */ - for( i = 0; i < 6; i++ ) { - GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 ); - GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 ); - } - - /* - * Key storage in KC - * Order: KL, KR, KA, KB - */ - memset( KC, 0, sizeof(KC) ); - - /* Store KL, KR */ - for( i = 0; i < 8; i++ ) - GET_UINT32_BE( KC[i], t, i * 4 ); - - /* Generate KA */ - for( i = 0; i < 4; ++i ) - KC[8 + i] = KC[i] ^ KC[4 + i]; - - camellia_feistel( KC + 8, SIGMA[0], KC + 10 ); - camellia_feistel( KC + 10, SIGMA[1], KC + 8 ); - - for( i = 0; i < 4; ++i ) - KC[8 + i] ^= KC[i]; - - camellia_feistel( KC + 8, SIGMA[2], KC + 10 ); - camellia_feistel( KC + 10, SIGMA[3], KC + 8 ); - - if( keybits > 128 ) { - /* Generate KB */ - for( i = 0; i < 4; ++i ) - KC[12 + i] = KC[4 + i] ^ KC[8 + i]; - - camellia_feistel( KC + 12, SIGMA[4], KC + 14 ); - camellia_feistel( KC + 14, SIGMA[5], KC + 12 ); - } - - /* - * Generating subkeys - */ - - /* Manipulating KL */ - SHIFT_AND_PLACE( idx, 0 ); - - /* Manipulating KR */ - if( keybits > 128 ) { - SHIFT_AND_PLACE( idx, 1 ); - } - - /* Manipulating KA */ - SHIFT_AND_PLACE( idx, 2 ); - - /* Manipulating KB */ - if( keybits > 128 ) { - SHIFT_AND_PLACE( idx, 3 ); - } - - /* Do transpositions */ - for( i = 0; i < 20; i++ ) { - if( transposes[idx][i] != -1 ) { - RK[32 + 12 * idx + i] = RK[transposes[idx][i]]; - } - } - - return( 0 ); -} - -/* - * Camellia key schedule (decryption) - */ -int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ) -{ - int idx, ret; - size_t i; - mbedtls_camellia_context cty; - uint32_t *RK; - uint32_t *SK; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( key != NULL ); - - mbedtls_camellia_init( &cty ); - - /* Also checks keybits */ - if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 ) - goto exit; - - ctx->nr = cty.nr; - idx = ( ctx->nr == 4 ); - - RK = ctx->rk; - SK = cty.rk + 24 * 2 + 8 * idx * 2; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 ) - { - *RK++ = *SK++; - *RK++ = *SK++; - } - - SK -= 2; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - -exit: - mbedtls_camellia_free( &cty ); - - return( ret ); -} - -/* - * Camellia-ECB block encryption/decryption - */ -int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - int NR; - uint32_t *RK, X[4]; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || - mode == MBEDTLS_CAMELLIA_DECRYPT ); - CAMELLIA_VALIDATE_RET( input != NULL ); - CAMELLIA_VALIDATE_RET( output != NULL ); - - ( (void) mode ); - - NR = ctx->nr; - RK = ctx->rk; - - GET_UINT32_BE( X[0], input, 0 ); - GET_UINT32_BE( X[1], input, 4 ); - GET_UINT32_BE( X[2], input, 8 ); - GET_UINT32_BE( X[3], input, 12 ); - - X[0] ^= *RK++; - X[1] ^= *RK++; - X[2] ^= *RK++; - X[3] ^= *RK++; - - while( NR ) { - --NR; - camellia_feistel( X, RK, X + 2 ); - RK += 2; - camellia_feistel( X + 2, RK, X ); - RK += 2; - camellia_feistel( X, RK, X + 2 ); - RK += 2; - camellia_feistel( X + 2, RK, X ); - RK += 2; - camellia_feistel( X, RK, X + 2 ); - RK += 2; - camellia_feistel( X + 2, RK, X ); - RK += 2; - - if( NR ) { - FL(X[0], X[1], RK[0], RK[1]); - RK += 2; - FLInv(X[2], X[3], RK[0], RK[1]); - RK += 2; - } - } - - X[2] ^= *RK++; - X[3] ^= *RK++; - X[0] ^= *RK++; - X[1] ^= *RK++; - - PUT_UINT32_BE( X[2], output, 0 ); - PUT_UINT32_BE( X[3], output, 4 ); - PUT_UINT32_BE( X[0], output, 8 ); - PUT_UINT32_BE( X[1], output, 12 ); - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * Camellia-CBC buffer encryption/decryption - */ -int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[16]; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || - mode == MBEDTLS_CAMELLIA_DECRYPT ); - CAMELLIA_VALIDATE_RET( iv != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); - - if( length % 16 ) - return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_CAMELLIA_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 16 ); - mbedtls_camellia_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_camellia_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * Camellia-CFB128 buffer encryption/decryption - */ -int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || - mode == MBEDTLS_CAMELLIA_DECRYPT ); - CAMELLIA_VALIDATE_RET( iv != NULL ); - CAMELLIA_VALIDATE_RET( iv_off != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); - - n = *iv_off; - if( n >= 16 ) - return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_CAMELLIA_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Camellia-CTR buffer encryption/decryption - */ -int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( nonce_counter != NULL ); - CAMELLIA_VALIDATE_RET( stream_block != NULL ); - CAMELLIA_VALIDATE_RET( nc_off != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); - - n = *nc_off; - if( n >= 16 ) - return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter, - stream_block ); - - for( i = 16; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* !MBEDTLS_CAMELLIA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Camellia test vectors from: - * - * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html: - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt - * (For each bitlength: Key 0, Nr 39) - */ -#define CAMELLIA_TESTS_ECB 2 - -static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = -{ - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, -}; - -static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] = -{ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] = -{ - { - { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, - 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, - { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE, - 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 } - }, - { - { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, - 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, - { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9, - 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 } - }, - { - { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, - 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, - { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C, - 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 } - } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define CAMELLIA_TESTS_CBC 3 - -static const unsigned char camellia_test_cbc_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } - , - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B } - , - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char camellia_test_cbc_iv[16] = - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F } -; - -static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] = -{ - { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A }, - { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 }, - { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF } - -}; - -static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] = -{ - { - { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0, - 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB }, - { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78, - 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 }, - { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B, - 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 } - }, - { - { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2, - 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 }, - { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42, - 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 }, - { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8, - 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 } - }, - { - { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A, - 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA }, - { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40, - 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 }, - { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA, - 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 } - } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Camellia-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc5528.html - */ - -static const unsigned char camellia_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char camellia_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char camellia_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char camellia_test_ctr_ct[3][48] = -{ - { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A, - 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F }, - { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4, - 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44, - 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7, - 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 }, - { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88, - 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73, - 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1, - 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD, - 0xDF, 0x50, 0x86, 0x96 } -}; - -static const int camellia_test_ctr_len[3] = - { 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/* - * Checkup routine - */ -int mbedtls_camellia_self_test( int verbose ) -{ - int i, j, u, v; - unsigned char key[32]; - unsigned char buf[64]; - unsigned char src[16]; - unsigned char dst[16]; -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - size_t offset, len; - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - - mbedtls_camellia_context ctx; - - memset( key, 0, 32 ); - - for( j = 0; j < 6; j++ ) { - u = j >> 1; - v = j & 1; - - if( verbose != 0 ) - mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, - (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc"); - - for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) { - memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u ); - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); - memcpy( src, camellia_test_ecb_cipher[u][i], 16 ); - memcpy( dst, camellia_test_ecb_plain[i], 16 ); - } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ - mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); - memcpy( src, camellia_test_ecb_plain[i], 16 ); - memcpy( dst, camellia_test_ecb_cipher[u][i], 16 ); - } - - mbedtls_camellia_crypt_ecb( &ctx, v, src, buf ); - - if( memcmp( buf, dst, 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for( j = 0; j < 6; j++ ) - { - u = j >> 1; - v = j & 1; - - if( verbose != 0 ) - mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, - ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); - - memcpy( src, camellia_test_cbc_iv, 16 ); - memcpy( dst, camellia_test_cbc_iv, 16 ); - memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); - } else { - mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); - } - - for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - memcpy( iv , src, 16 ); - memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); - memcpy( dst, camellia_test_cbc_plain[i], 16 ); - } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ - memcpy( iv , dst, 16 ); - memcpy( src, camellia_test_cbc_plain[i], 16 ); - memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); - } - - mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); - - if( memcmp( buf, dst, 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " CAMELLIA-CTR-128 (%s): ", - ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); - - memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 ); - memcpy( key, camellia_test_ctr_key[u], 16 ); - - offset = 0; - mbedtls_camellia_setkey_enc( &ctx, key, 128 ); - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) - { - len = camellia_test_ctr_len[u]; - memcpy( buf, camellia_test_ctr_ct[u], len ); - - mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, - buf, buf ); - - if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - } - else - { - len = camellia_test_ctr_len[u]; - memcpy( buf, camellia_test_ctr_pt[u], len ); - - mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, - buf, buf ); - - if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CAMELLIA_C */ diff --git a/library/ccm.c b/library/ccm.c deleted file mode 100644 index a7e360ecf4..0000000000 --- a/library/ccm.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * NIST SP800-38C compliant CCM implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * Definition of CCM: - * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - * RFC 3610 "Counter with CBC-MAC (CCM)" - * - * Related: - * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CCM_C) - -#include "mbedtls/ccm.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#if !defined(MBEDTLS_CCM_ALT) - -#define CCM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT ) -#define CCM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define CCM_ENCRYPT 0 -#define CCM_DECRYPT 1 - -/* - * Initialize context - */ -void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) -{ - CCM_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); -} - -int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( key != NULL ); - - cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, - MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Free context - */ -void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) -{ - if( ctx == NULL ) - return; - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); -} - -/* - * Macros for common operations. - * Results in smaller compiled code than static inline functions. - */ - -/* - * Update the CBC-MAC state in y using a block in b - * (Always using b as the source helps the compiler optimise a bit better.) - */ -#define UPDATE_CBC_MAC \ - for( i = 0; i < 16; i++ ) \ - y[i] ^= b[i]; \ - \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ - return( ret ); - -/* - * Encrypt or decrypt a partial block with CTR - * Warning: using b for temporary storage! src and dst must not be b! - * This avoids allocating one more 16 bytes buffer while allowing src == dst. - */ -#define CTR_CRYPT( dst, src, len ) \ - do \ - { \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, \ - 16, b, &olen ) ) != 0 ) \ - { \ - return( ret ); \ - } \ - \ - for( i = 0; i < (len); i++ ) \ - (dst)[i] = (src)[i] ^ b[i]; \ - } while( 0 ) - -/* - * Authenticated encryption or decryption - */ -static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - int ret; - unsigned char i; - unsigned char q; - size_t len_left, olen; - unsigned char b[16]; - unsigned char y[16]; - unsigned char ctr[16]; - const unsigned char *src; - unsigned char *dst; - - /* - * Check length requirements: SP800-38C A.1 - * Additional requirement: a < 2^16 - 2^8 to simplify the code. - * 'length' checked later (when writing it to the first block) - * - * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4). - */ - if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - /* Also implies q is within bounds */ - if( iv_len < 7 || iv_len > 13 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - if( add_len > 0xFF00 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - q = 16 - 1 - (unsigned char) iv_len; - - /* - * First block B_0: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - * iv_len+1 .. 15 length - * - * With flags as (bits): - * 7 0 - * 6 add present? - * 5 .. 3 (t - 2) / 2 - * 2 .. 0 q - 1 - */ - b[0] = 0; - b[0] |= ( add_len > 0 ) << 6; - b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; - b[0] |= q - 1; - - memcpy( b + 1, iv, iv_len ); - - for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) - b[15-i] = (unsigned char)( len_left & 0xFF ); - - if( len_left > 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - - /* Start CBC-MAC with first block */ - memset( y, 0, 16 ); - UPDATE_CBC_MAC; - - /* - * If there is additional data, update CBC-MAC with - * add_len, add, 0 (padding to a block boundary) - */ - if( add_len > 0 ) - { - size_t use_len; - len_left = add_len; - src = add; - - memset( b, 0, 16 ); - b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); - b[1] = (unsigned char)( ( add_len ) & 0xFF ); - - use_len = len_left < 16 - 2 ? len_left : 16 - 2; - memcpy( b + 2, src, use_len ); - len_left -= use_len; - src += use_len; - - UPDATE_CBC_MAC; - - while( len_left > 0 ) - { - use_len = len_left > 16 ? 16 : len_left; - - memset( b, 0, 16 ); - memcpy( b, src, use_len ); - UPDATE_CBC_MAC; - - len_left -= use_len; - src += use_len; - } - } - - /* - * Prepare counter block for encryption: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - * iv_len+1 .. 15 counter (initially 1) - * - * With flags as (bits): - * 7 .. 3 0 - * 2 .. 0 q - 1 - */ - ctr[0] = q - 1; - memcpy( ctr + 1, iv, iv_len ); - memset( ctr + 1 + iv_len, 0, q ); - ctr[15] = 1; - - /* - * Authenticate and {en,de}crypt the message. - * - * The only difference between encryption and decryption is - * the respective order of authentication and {en,de}cryption. - */ - len_left = length; - src = input; - dst = output; - - while( len_left > 0 ) - { - size_t use_len = len_left > 16 ? 16 : len_left; - - if( mode == CCM_ENCRYPT ) - { - memset( b, 0, 16 ); - memcpy( b, src, use_len ); - UPDATE_CBC_MAC; - } - - CTR_CRYPT( dst, src, use_len ); - - if( mode == CCM_DECRYPT ) - { - memset( b, 0, 16 ); - memcpy( b, dst, use_len ); - UPDATE_CBC_MAC; - } - - dst += use_len; - src += use_len; - len_left -= use_len; - - /* - * Increment counter. - * No need to check for overflow thanks to the length check above. - */ - for( i = 0; i < q; i++ ) - if( ++ctr[15-i] != 0 ) - break; - } - - /* - * Authentication: reset counter and crypt/mask internal tag - */ - for( i = 0; i < q; i++ ) - ctr[15-i] = 0; - - CTR_CRYPT( y, y, 16 ); - memcpy( tag, y, tag_len ); - - return( 0 ); -} - -/* - * Authenticated encryption - */ -int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, - add, add_len, input, output, tag, tag_len ) ); -} - -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( tag_len == 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add, - add_len, input, output, tag, tag_len ) ); -} - -/* - * Authenticated decryption - */ -int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ) -{ - int ret; - unsigned char check_tag[16]; - unsigned char i; - int diff; - - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - - if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, check_tag, tag_len ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_platform_zeroize( output, length ); - return( MBEDTLS_ERR_CCM_AUTH_FAILED ); - } - - return( 0 ); -} - -int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ) -{ - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - - if( tag_len == 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add, - add_len, input, output, tag, tag_len ) ); -} -#endif /* !MBEDTLS_CCM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/* - * Examples 1 to 3 from SP800-38C Appendix C - */ - -#define NB_TESTS 3 -#define CCM_SELFTEST_PT_MAX_LEN 24 -#define CCM_SELFTEST_CT_MAX_LEN 32 -/* - * The data is the same for all tests, only the used length changes - */ -static const unsigned char key_test_data[] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f -}; - -static const unsigned char iv_test_data[] = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b -}; - -static const unsigned char ad_test_data[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 -}; - -static const unsigned char msg_test_data[CCM_SELFTEST_PT_MAX_LEN] = { - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -}; - -static const size_t iv_len_test_data [NB_TESTS] = { 7, 8, 12 }; -static const size_t add_len_test_data[NB_TESTS] = { 8, 16, 20 }; -static const size_t msg_len_test_data[NB_TESTS] = { 4, 16, 24 }; -static const size_t tag_len_test_data[NB_TESTS] = { 4, 6, 8 }; - -static const unsigned char res_test_data[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = { - { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, - { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, - 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, - 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, - { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, - 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, - 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, - 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } -}; - -int mbedtls_ccm_self_test( int verbose ) -{ - mbedtls_ccm_context ctx; - /* - * Some hardware accelerators require the input and output buffers - * would be in RAM, because the flash is not accessible. - * Use buffers on the stack to hold the test vectors data. - */ - unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN]; - unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN]; - size_t i; - int ret; - - mbedtls_ccm_init( &ctx ); - - if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key_test_data, - 8 * sizeof key_test_data ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " CCM: setup failed" ); - - return( 1 ); - } - - for( i = 0; i < NB_TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); - - memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN ); - memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN ); - memcpy( plaintext, msg_test_data, msg_len_test_data[i] ); - - ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len_test_data[i], - iv_test_data, iv_len_test_data[i], - ad_test_data, add_len_test_data[i], - plaintext, ciphertext, - ciphertext + msg_len_test_data[i], - tag_len_test_data[i] ); - - if( ret != 0 || - memcmp( ciphertext, res_test_data[i], - msg_len_test_data[i] + tag_len_test_data[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN ); - - ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len_test_data[i], - iv_test_data, iv_len_test_data[i], - ad_test_data, add_len_test_data[i], - ciphertext, plaintext, - ciphertext + msg_len_test_data[i], - tag_len_test_data[i] ); - - if( ret != 0 || - memcmp( plaintext, msg_test_data, msg_len_test_data[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - mbedtls_ccm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_CCM_C */ diff --git a/library/chacha20.c b/library/chacha20.c deleted file mode 100644 index 8a3610f0e0..0000000000 --- a/library/chacha20.c +++ /dev/null @@ -1,570 +0,0 @@ -/** - * \file chacha20.c - * - * \brief ChaCha20 cipher. - * - * \author Daniel King - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CHACHA20_C) - -#include "mbedtls/chacha20.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_CHACHA20_ALT) - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Parameter validation macros */ -#define CHACHA20_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) -#define CHACHA20_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t) (data)[offset] \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ - ) - -#define ROTL32( value, amount ) \ - ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) ) - -#define CHACHA20_CTR_INDEX ( 12U ) - -#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U ) - -/** - * \brief ChaCha20 quarter round operation. - * - * The quarter round is defined as follows (from RFC 7539): - * 1. a += b; d ^= a; d <<<= 16; - * 2. c += d; b ^= c; b <<<= 12; - * 3. a += b; d ^= a; d <<<= 8; - * 4. c += d; b ^= c; b <<<= 7; - * - * \param state ChaCha20 state to modify. - * \param a The index of 'a' in the state. - * \param b The index of 'b' in the state. - * \param c The index of 'c' in the state. - * \param d The index of 'd' in the state. - */ -static inline void chacha20_quarter_round( uint32_t state[16], - size_t a, - size_t b, - size_t c, - size_t d ) -{ - /* a += b; d ^= a; d <<<= 16; */ - state[a] += state[b]; - state[d] ^= state[a]; - state[d] = ROTL32( state[d], 16 ); - - /* c += d; b ^= c; b <<<= 12 */ - state[c] += state[d]; - state[b] ^= state[c]; - state[b] = ROTL32( state[b], 12 ); - - /* a += b; d ^= a; d <<<= 8; */ - state[a] += state[b]; - state[d] ^= state[a]; - state[d] = ROTL32( state[d], 8 ); - - /* c += d; b ^= c; b <<<= 7; */ - state[c] += state[d]; - state[b] ^= state[c]; - state[b] = ROTL32( state[b], 7 ); -} - -/** - * \brief Perform the ChaCha20 inner block operation. - * - * This function performs two rounds: the column round and the - * diagonal round. - * - * \param state The ChaCha20 state to update. - */ -static void chacha20_inner_block( uint32_t state[16] ) -{ - chacha20_quarter_round( state, 0, 4, 8, 12 ); - chacha20_quarter_round( state, 1, 5, 9, 13 ); - chacha20_quarter_round( state, 2, 6, 10, 14 ); - chacha20_quarter_round( state, 3, 7, 11, 15 ); - - chacha20_quarter_round( state, 0, 5, 10, 15 ); - chacha20_quarter_round( state, 1, 6, 11, 12 ); - chacha20_quarter_round( state, 2, 7, 8, 13 ); - chacha20_quarter_round( state, 3, 4, 9, 14 ); -} - -/** - * \brief Generates a keystream block. - * - * \param initial_state The initial ChaCha20 state (key, nonce, counter). - * \param keystream Generated keystream bytes are written to this buffer. - */ -static void chacha20_block( const uint32_t initial_state[16], - unsigned char keystream[64] ) -{ - uint32_t working_state[16]; - size_t i; - - memcpy( working_state, - initial_state, - CHACHA20_BLOCK_SIZE_BYTES ); - - for( i = 0U; i < 10U; i++ ) - chacha20_inner_block( working_state ); - - working_state[ 0] += initial_state[ 0]; - working_state[ 1] += initial_state[ 1]; - working_state[ 2] += initial_state[ 2]; - working_state[ 3] += initial_state[ 3]; - working_state[ 4] += initial_state[ 4]; - working_state[ 5] += initial_state[ 5]; - working_state[ 6] += initial_state[ 6]; - working_state[ 7] += initial_state[ 7]; - working_state[ 8] += initial_state[ 8]; - working_state[ 9] += initial_state[ 9]; - working_state[10] += initial_state[10]; - working_state[11] += initial_state[11]; - working_state[12] += initial_state[12]; - working_state[13] += initial_state[13]; - working_state[14] += initial_state[14]; - working_state[15] += initial_state[15]; - - for( i = 0U; i < 16; i++ ) - { - size_t offset = i * 4U; - - keystream[offset ] = (unsigned char)( working_state[i] ); - keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 ); - keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 ); - keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 ); - } - - mbedtls_platform_zeroize( working_state, sizeof( working_state ) ); -} - -void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ) -{ - CHACHA20_VALIDATE( ctx != NULL ); - - mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) ); - mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); - - /* Initially, there's no keystream bytes available */ - ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; -} - -void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ) -{ - if( ctx != NULL ) - { - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) ); - } -} - -int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, - const unsigned char key[32] ) -{ - CHACHA20_VALIDATE_RET( ctx != NULL ); - CHACHA20_VALIDATE_RET( key != NULL ); - - /* ChaCha20 constants - the string "expand 32-byte k" */ - ctx->state[0] = 0x61707865; - ctx->state[1] = 0x3320646e; - ctx->state[2] = 0x79622d32; - ctx->state[3] = 0x6b206574; - - /* Set key */ - ctx->state[4] = BYTES_TO_U32_LE( key, 0 ); - ctx->state[5] = BYTES_TO_U32_LE( key, 4 ); - ctx->state[6] = BYTES_TO_U32_LE( key, 8 ); - ctx->state[7] = BYTES_TO_U32_LE( key, 12 ); - ctx->state[8] = BYTES_TO_U32_LE( key, 16 ); - ctx->state[9] = BYTES_TO_U32_LE( key, 20 ); - ctx->state[10] = BYTES_TO_U32_LE( key, 24 ); - ctx->state[11] = BYTES_TO_U32_LE( key, 28 ); - - return( 0 ); -} - -int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, - const unsigned char nonce[12], - uint32_t counter ) -{ - CHACHA20_VALIDATE_RET( ctx != NULL ); - CHACHA20_VALIDATE_RET( nonce != NULL ); - - /* Counter */ - ctx->state[12] = counter; - - /* Nonce */ - ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 ); - ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 ); - ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 ); - - mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); - - /* Initially, there's no keystream bytes available */ - ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; - - return( 0 ); -} - -int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, - size_t size, - const unsigned char *input, - unsigned char *output ) -{ - size_t offset = 0U; - size_t i; - - CHACHA20_VALIDATE_RET( ctx != NULL ); - CHACHA20_VALIDATE_RET( size == 0 || input != NULL ); - CHACHA20_VALIDATE_RET( size == 0 || output != NULL ); - - /* Use leftover keystream bytes, if available */ - while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES ) - { - output[offset] = input[offset] - ^ ctx->keystream8[ctx->keystream_bytes_used]; - - ctx->keystream_bytes_used++; - offset++; - size--; - } - - /* Process full blocks */ - while( size >= CHACHA20_BLOCK_SIZE_BYTES ) - { - /* Generate new keystream block and increment counter */ - chacha20_block( ctx->state, ctx->keystream8 ); - ctx->state[CHACHA20_CTR_INDEX]++; - - for( i = 0U; i < 64U; i += 8U ) - { - output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ]; - output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1]; - output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2]; - output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3]; - output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4]; - output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5]; - output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6]; - output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7]; - } - - offset += CHACHA20_BLOCK_SIZE_BYTES; - size -= CHACHA20_BLOCK_SIZE_BYTES; - } - - /* Last (partial) block */ - if( size > 0U ) - { - /* Generate new keystream block and increment counter */ - chacha20_block( ctx->state, ctx->keystream8 ); - ctx->state[CHACHA20_CTR_INDEX]++; - - for( i = 0U; i < size; i++) - { - output[offset + i] = input[offset + i] ^ ctx->keystream8[i]; - } - - ctx->keystream_bytes_used = size; - - } - - return( 0 ); -} - -int mbedtls_chacha20_crypt( const unsigned char key[32], - const unsigned char nonce[12], - uint32_t counter, - size_t data_len, - const unsigned char* input, - unsigned char* output ) -{ - mbedtls_chacha20_context ctx; - int ret; - - CHACHA20_VALIDATE_RET( key != NULL ); - CHACHA20_VALIDATE_RET( nonce != NULL ); - CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL ); - CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL ); - - mbedtls_chacha20_init( &ctx ); - - ret = mbedtls_chacha20_setkey( &ctx, key ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chacha20_starts( &ctx, nonce, counter ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chacha20_update( &ctx, data_len, input, output ); - -cleanup: - mbedtls_chacha20_free( &ctx ); - return( ret ); -} - -#endif /* !MBEDTLS_CHACHA20_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_keys[2][32] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 - } -}; - -static const unsigned char test_nonces[2][12] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02 - } -}; - -static const uint32_t test_counters[2] = -{ - 0U, - 1U -}; - -static const unsigned char test_input[2][375] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, - 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, - 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, - 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, - 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, - 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, - 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, - 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, - 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, - 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, - 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, - 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, - 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, - 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, - 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, - 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63, - 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, - 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, - 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, - 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, - 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f - } -}; - -static const unsigned char test_output[2][375] = -{ - { - 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, - 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, - 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, - 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, - 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, - 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, - 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, - 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86 - }, - { - 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde, - 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70, - 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd, - 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec, - 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15, - 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05, - 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f, - 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d, - 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa, - 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e, - 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7, - 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50, - 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05, - 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c, - 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05, - 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a, - 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0, - 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66, - 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4, - 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d, - 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91, - 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28, - 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87, - 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b, - 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2, - 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f, - 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76, - 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c, - 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b, - 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84, - 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd, - 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b, - 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe, - 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0, - 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80, - 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f, - 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3, - 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62, - 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91, - 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6, - 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64, - 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85, - 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41, - 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab, - 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba, - 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd, - 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21 - } -}; - -static const size_t test_lengths[2] = -{ - 64U, - 375U -}; - -#define ASSERT( cond, args ) \ - do \ - { \ - if( ! ( cond ) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf args; \ - \ - return( -1 ); \ - } \ - } \ - while( 0 ) - -int mbedtls_chacha20_self_test( int verbose ) -{ - unsigned char output[381]; - unsigned i; - int ret; - - for( i = 0U; i < 2U; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " ChaCha20 test %u ", i ); - - ret = mbedtls_chacha20_crypt( test_keys[i], - test_nonces[i], - test_counters[i], - test_lengths[i], - test_input[i], - output ); - - ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); - - ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ), - ( "failed (output)\n" ) ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* !MBEDTLS_CHACHA20_C */ diff --git a/library/chachapoly.c b/library/chachapoly.c deleted file mode 100644 index dc643dd618..0000000000 --- a/library/chachapoly.c +++ /dev/null @@ -1,540 +0,0 @@ -/** - * \file chachapoly.c - * - * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - -#include "mbedtls/chachapoly.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_CHACHAPOLY_ALT) - -/* Parameter validation macros */ -#define CHACHAPOLY_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ) -#define CHACHAPOLY_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define CHACHAPOLY_STATE_INIT ( 0 ) -#define CHACHAPOLY_STATE_AAD ( 1 ) -#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */ -#define CHACHAPOLY_STATE_FINISHED ( 3 ) - -/** - * \brief Adds nul bytes to pad the AAD for Poly1305. - * - * \param ctx The ChaCha20-Poly1305 context. - */ -static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) -{ - uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U ); - unsigned char zeroes[15]; - - if( partial_block_len == 0U ) - return( 0 ); - - memset( zeroes, 0, sizeof( zeroes ) ); - - return( mbedtls_poly1305_update( &ctx->poly1305_ctx, - zeroes, - 16U - partial_block_len ) ); -} - -/** - * \brief Adds nul bytes to pad the ciphertext for Poly1305. - * - * \param ctx The ChaCha20-Poly1305 context. - */ -static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) -{ - uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); - unsigned char zeroes[15]; - - if( partial_block_len == 0U ) - return( 0 ); - - memset( zeroes, 0, sizeof( zeroes ) ); - return( mbedtls_poly1305_update( &ctx->poly1305_ctx, - zeroes, - 16U - partial_block_len ) ); -} - -void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ) -{ - CHACHAPOLY_VALIDATE( ctx != NULL ); - - mbedtls_chacha20_init( &ctx->chacha20_ctx ); - mbedtls_poly1305_init( &ctx->poly1305_ctx ); - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_INIT; - ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; -} - -void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_chacha20_free( &ctx->chacha20_ctx ); - mbedtls_poly1305_free( &ctx->poly1305_ctx ); - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_INIT; - ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; -} - -int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, - const unsigned char key[32] ) -{ - int ret; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( key != NULL ); - - ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); - - return( ret ); -} - -int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, - const unsigned char nonce[12], - mbedtls_chachapoly_mode_t mode ) -{ - int ret; - unsigned char poly1305_key[64]; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( nonce != NULL ); - - /* Set counter = 0, will be update to 1 when generating Poly1305 key */ - ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U ); - if( ret != 0 ) - goto cleanup; - - /* Generate the Poly1305 key by getting the ChaCha20 keystream output with - * counter = 0. This is the same as encrypting a buffer of zeroes. - * Only the first 256-bits (32 bytes) of the key is used for Poly1305. - * The other 256 bits are discarded. - */ - memset( poly1305_key, 0, sizeof( poly1305_key ) ); - ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ), - poly1305_key, poly1305_key ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key ); - - if( ret == 0 ) - { - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_AAD; - ctx->mode = mode; - } - -cleanup: - mbedtls_platform_zeroize( poly1305_key, 64U ); - return( ret ); -} - -int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, - const unsigned char *aad, - size_t aad_len ) -{ - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); - - if( ctx->state != CHACHAPOLY_STATE_AAD ) - return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); - - ctx->aad_len += aad_len; - - return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) ); -} - -int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL ); - CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL ); - - if( ( ctx->state != CHACHAPOLY_STATE_AAD ) && - ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) ) - { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); - } - - if( ctx->state == CHACHAPOLY_STATE_AAD ) - { - ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; - - ret = chachapoly_pad_aad( ctx ); - if( ret != 0 ) - return( ret ); - } - - ctx->ciphertext_len += len; - - if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT ) - { - ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len ); - if( ret != 0 ) - return( ret ); - } - else /* DECRYPT */ - { - ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); - if( ret != 0 ) - return( ret ); - } - - return( 0 ); -} - -int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, - unsigned char mac[16] ) -{ - int ret; - unsigned char len_block[16]; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( mac != NULL ); - - if( ctx->state == CHACHAPOLY_STATE_INIT ) - { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); - } - - if( ctx->state == CHACHAPOLY_STATE_AAD ) - { - ret = chachapoly_pad_aad( ctx ); - if( ret != 0 ) - return( ret ); - } - else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) - { - ret = chachapoly_pad_ciphertext( ctx ); - if( ret != 0 ) - return( ret ); - } - - ctx->state = CHACHAPOLY_STATE_FINISHED; - - /* The lengths of the AAD and ciphertext are processed by - * Poly1305 as the final 128-bit block, encoded as little-endian integers. - */ - len_block[ 0] = (unsigned char)( ctx->aad_len ); - len_block[ 1] = (unsigned char)( ctx->aad_len >> 8 ); - len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 ); - len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 ); - len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 ); - len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 ); - len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 ); - len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 ); - len_block[ 8] = (unsigned char)( ctx->ciphertext_len ); - len_block[ 9] = (unsigned char)( ctx->ciphertext_len >> 8 ); - len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 ); - len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 ); - len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 ); - len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 ); - len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 ); - len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 ); - - ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); - - return( ret ); -} - -static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, - mbedtls_chachapoly_mode_t mode, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16] ) -{ - int ret; - - ret = mbedtls_chachapoly_starts( ctx, nonce, mode ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chachapoly_update( ctx, length, input, output ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chachapoly_finish( ctx, tag ); - -cleanup: - return( ret ); -} - -int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16] ) -{ - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( nonce != NULL ); - CHACHAPOLY_VALIDATE_RET( tag != NULL ); - CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL ); - - return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, - length, nonce, aad, aad_len, - input, output, tag ) ); -} - -int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char tag[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char check_tag[16]; - size_t i; - int diff; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( nonce != NULL ); - CHACHAPOLY_VALIDATE_RET( tag != NULL ); - CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL ); - - if( ( ret = chachapoly_crypt_and_tag( ctx, - MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, - aad, aad_len, input, output, check_tag ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < sizeof( check_tag ); i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_platform_zeroize( output, length ); - return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ); - } - - return( 0 ); -} - -#endif /* MBEDTLS_CHACHAPOLY_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_key[1][32] = -{ - { - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f - } -}; - -static const unsigned char test_nonce[1][12] = -{ - { - 0x07, 0x00, 0x00, 0x00, /* 32-bit common part */ - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */ - } -}; - -static const unsigned char test_aad[1][12] = -{ - { - 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7 - } -}; - -static const size_t test_aad_len[1] = -{ - 12U -}; - -static const unsigned char test_input[1][114] = -{ - { - 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, - 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, - 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, - 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, - 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, - 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, - 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, - 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, - 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, - 0x74, 0x2e - } -}; - -static const unsigned char test_output[1][114] = -{ - { - 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, - 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, - 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, - 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, - 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, - 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, - 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, - 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, - 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, - 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, - 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, - 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, - 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, - 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, - 0x61, 0x16 - } -}; - -static const size_t test_input_len[1] = -{ - 114U -}; - -static const unsigned char test_mac[1][16] = -{ - { - 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, - 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 - } -}; - -#define ASSERT( cond, args ) \ - do \ - { \ - if( ! ( cond ) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf args; \ - \ - return( -1 ); \ - } \ - } \ - while( 0 ) - -int mbedtls_chachapoly_self_test( int verbose ) -{ - mbedtls_chachapoly_context ctx; - unsigned i; - int ret; - unsigned char output[200]; - unsigned char mac[16]; - - for( i = 0U; i < 1U; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); - - mbedtls_chachapoly_init( &ctx ); - - ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); - ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) ); - - ret = mbedtls_chachapoly_encrypt_and_tag( &ctx, - test_input_len[i], - test_nonce[i], - test_aad[i], - test_aad_len[i], - test_input[i], - output, - mac ); - - ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) ); - - ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ), - ( "failure (wrong output)\n" ) ); - - ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), - ( "failure (wrong MAC)\n" ) ); - - mbedtls_chachapoly_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CHACHAPOLY_C */ diff --git a/library/cipher.c b/library/cipher.c deleted file mode 100644 index 3cdd07f8f6..0000000000 --- a/library/cipher.c +++ /dev/null @@ -1,1540 +0,0 @@ -/** - * \file cipher.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "mbedtls/cipher.h" -#include "mbedtls/cipher_internal.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_CMAC_C) -#include "mbedtls/cmac.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_NIST_KW_C) -#include "mbedtls/nist_kw.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#define CIPHER_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ) -#define CIPHER_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/* Compare the contents of two buffers in constant time. - * Returns 0 if the contents are bitwise identical, otherwise returns - * a non-zero value. - * This is currently only used by GCM and ChaCha20+Poly1305. - */ -static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, - size_t len ) -{ - const unsigned char *p1 = (const unsigned char*) v1; - const unsigned char *p2 = (const unsigned char*) v2; - size_t i; - unsigned char diff; - - for( diff = 0, i = 0; i < len; i++ ) - diff |= p1[i] ^ p2[i]; - - return( (int)diff ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -static int supported_init = 0; - -const int *mbedtls_cipher_list( void ) -{ - const mbedtls_cipher_definition_t *def; - int *type; - - if( ! supported_init ) - { - def = mbedtls_cipher_definitions; - type = mbedtls_cipher_supported; - - while( def->type != 0 ) - *type++ = (*def++).type; - - *type = 0; - - supported_init = 1; - } - - return( mbedtls_cipher_supported ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( - const mbedtls_cipher_type_t cipher_type ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->type == cipher_type ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( - const char *cipher_name ) -{ - const mbedtls_cipher_definition_t *def; - - if( NULL == cipher_name ) - return( NULL ); - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( ! strcmp( def->info->name, cipher_name ) ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( - const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->info->base->cipher == cipher_id && - def->info->key_bitlen == (unsigned) key_bitlen && - def->info->mode == mode ) - return( def->info ); - - return( NULL ); -} - -void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) -{ - CIPHER_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); -} - -void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - if( ctx->cipher_ctx != NULL ) - { - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED ) - { - /* xxx_free() doesn't allow to return failures. */ - (void) psa_destroy_key( cipher_psa->slot ); - } - - mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) ); - mbedtls_free( cipher_psa ); - } - - mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); - return; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_CMAC_C) - if( ctx->cmac_ctx ) - { - mbedtls_platform_zeroize( ctx->cmac_ctx, - sizeof( mbedtls_cmac_context_t ) ); - mbedtls_free( ctx->cmac_ctx ); - } -#endif - - if( ctx->cipher_ctx ) - ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); - - mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); -} - -int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); - - if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - - ctx->cipher_info = cipher_info; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /* - * Ignore possible errors caused by a cipher mode that doesn't use padding - */ -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); -#else - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); -#endif -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - - return( 0 ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info, - size_t taglen ) -{ - psa_algorithm_t alg; - mbedtls_cipher_context_psa *cipher_psa; - - if( NULL == cipher_info || NULL == ctx ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* Check that the underlying cipher mode and cipher type are - * supported by the underlying PSA Crypto implementation. */ - alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen ); - if( alg == 0 ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); - - cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) ); - if( cipher_psa == NULL ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - cipher_psa->alg = alg; - ctx->cipher_ctx = cipher_psa; - ctx->cipher_info = cipher_info; - ctx->psa_enabled = 1; - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( key != NULL ); - CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT || - operation == MBEDTLS_DECRYPT ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8; - - psa_status_t status; - psa_key_type_t key_type; - psa_key_usage_t key_usage; - psa_key_policy_t key_policy; - - /* PSA Crypto API only accepts byte-aligned keys. */ - if( key_bitlen % 8 != 0 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* Don't allow keys to be set multiple times. */ - if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - key_type = mbedtls_psa_translate_cipher_type( - ctx->cipher_info->type ); - if( key_type == 0 ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - /* Allocate a key slot to use. */ - status = psa_allocate_key( &cipher_psa->slot ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - /* Indicate that we own the key slot and need to - * destroy it in mbedtls_cipher_free(). */ - cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED; - - /* From that point on, the responsibility for destroying the - * key slot is on mbedtls_cipher_free(). This includes the case - * where the policy setup or key import below fail, as - * mbedtls_cipher_free() needs to be called in any case. */ - - /* Setup policy for the new key slot. */ - key_policy = psa_key_policy_init(); - - /* Mbed TLS' cipher layer doesn't enforce the mode of operation - * (encrypt vs. decrypt): it is possible to setup a key for encryption - * and use it for AEAD decryption. Until tests relying on this - * are changed, allow any usage in PSA. */ - /* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */ - key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT; - psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg ); - status = psa_set_key_policy( cipher_psa->slot, &key_policy ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - /* Populate new key slot. */ - status = psa_import_key( cipher_psa->slot, - key_type, key, key_bytelen ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && - (int) ctx->cipher_info->key_bitlen != key_bitlen ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - - /* - * For OFB, CFB and CTR mode always use the encryption key schedule - */ - if( MBEDTLS_ENCRYPT == operation || - MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) - { - return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); - } - - if( MBEDTLS_DECRYPT == operation ) - return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); - - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -} - -int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len ) -{ - size_t actual_iv_size; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* avoid buffer overflow in ctx->iv */ - if( iv_len > MBEDTLS_MAX_IV_LENGTH ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) - actual_iv_size = iv_len; - else - { - actual_iv_size = ctx->cipher_info->iv_size; - - /* avoid reading past the end of input buffer */ - if( actual_iv_size > iv_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CHACHA20_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) - { - if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, - iv, - 0U ) ) /* Initial counter value */ - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - } -#endif - - if ( actual_iv_size != 0 ) - { - memcpy( ctx->iv, iv, actual_iv_size ); - ctx->iv_size = actual_iv_size; - } - - return( 0 ); -} - -int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* We don't support resetting PSA-based - * cipher contexts, yet. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - ctx->unprocessed_len = 0; - - return( 0 ); -} - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, - ctx->iv, ctx->iv_size, ad, ad_len ) ); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int result; - mbedtls_chachapoly_mode_t mode; - - mode = ( ctx->operation == MBEDTLS_ENCRYPT ) - ? MBEDTLS_CHACHAPOLY_ENCRYPT - : MBEDTLS_CHACHAPOLY_DECRYPT; - - result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ctx->iv, - mode ); - if ( result != 0 ) - return( result ); - - return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ad, ad_len ) ); - } -#endif - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, - size_t ilen, unsigned char *output, size_t *olen ) -{ - int ret; - size_t block_size; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - *olen = 0; - block_size = mbedtls_cipher_get_block_size( ctx ); - - if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) - { - if( ilen != block_size ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - *olen = ilen; - - if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, - ctx->operation, input, output ) ) ) - { - return( ret ); - } - - return( 0 ); - } - -#if defined(MBEDTLS_GCM_C) - if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) - { - *olen = ilen; - return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, - output ) ); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) - { - *olen = ilen; - return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ilen, input, output ) ); - } -#endif - - if ( 0 == block_size ) - { - return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); - } - - if( input == output && - ( ctx->unprocessed_len != 0 || ilen % block_size ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) - { - size_t copy_len = 0; - - /* - * If there is not enough data for a full block, cache it. - */ - if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && - ilen <= block_size - ctx->unprocessed_len ) || - ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && - ilen < block_size - ctx->unprocessed_len ) || - ( ctx->operation == MBEDTLS_ENCRYPT && - ilen < block_size - ctx->unprocessed_len ) ) - { - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - ilen ); - - ctx->unprocessed_len += ilen; - return( 0 ); - } - - /* - * Process cached data first - */ - if( 0 != ctx->unprocessed_len ) - { - copy_len = block_size - ctx->unprocessed_len; - - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - copy_len ); - - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, block_size, ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - *olen += block_size; - output += block_size; - ctx->unprocessed_len = 0; - - input += copy_len; - ilen -= copy_len; - } - - /* - * Cache final, incomplete block - */ - if( 0 != ilen ) - { - if( 0 == block_size ) - { - return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); - } - - /* Encryption: only cache partial blocks - * Decryption w/ padding: always keep at least one whole block - * Decryption w/o padding: only cache partial blocks - */ - copy_len = ilen % block_size; - if( copy_len == 0 && - ctx->operation == MBEDTLS_DECRYPT && - NULL != ctx->add_padding) - { - copy_len = block_size; - } - - memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), - copy_len ); - - ctx->unprocessed_len += copy_len; - ilen -= copy_len; - } - - /* - * Process remaining full blocks - */ - if( ilen ) - { - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen += ilen; - } - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, - ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, - input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) - { - if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, - ctx->unprocessed_data, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) - { - if( ctx->unprocessed_len > 0 ) { - /* We can only process an entire data unit at a time. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ); - if( ret != 0 ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) - { - if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, - ilen, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_STREAM */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) -/* - * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len - */ -static void add_pkcs_padding( unsigned char *output, size_t output_len, - size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i; - - for( i = 0; i < padding_len; i++ ) - output[data_len + i] = (unsigned char) padding_len; -} - -static int get_pkcs_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len, - * so pick input_len, which is usually 8 or 16 (one block) */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len; i++ ) - bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ - -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) -/* - * One and zeros padding: fill with 80 00 ... 00 - */ -static void add_one_and_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - output[data_len] = 0x80; - for( i = 1; i < padding_len; i++ ) - output[data_len + i] = 0x00; -} - -static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done, bad; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - bad = 0x80; - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i - 1] != 0 ); - *data_len |= ( i - 1 ) * ( done != prev_done ); - bad ^= input[i - 1] * ( done != prev_done ); - } - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); - -} -#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) -/* - * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length - */ -static void add_zeros_and_len_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - for( i = 1; i < padding_len; i++ ) - output[data_len + i - 1] = 0x00; - output[output_len - 1] = (unsigned char) padding_len; -} - -static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len - 1; i++ ) - bad |= input[i] * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) -/* - * Zero padding: fill with 00 ... 00 - */ -static void add_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t i; - - for( i = data_len; i < output_len; i++ ) - output[i] = 0x00; -} - -static int get_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i-1] != 0 ); - *data_len |= i * ( done != prev_done ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ - -/* - * No padding: don't pad :) - * - * There is no add_padding function (check for NULL in mbedtls_cipher_finish) - * but a trivial get_padding function - */ -static int get_no_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = input_len; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - *olen = 0; - - if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode || - MBEDTLS_MODE_GCM == ctx->cipher_info->mode || - MBEDTLS_MODE_XTS == ctx->cipher_info->mode || - MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) - { - return( 0 ); - } - - if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || - ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) - { - return( 0 ); - } - - if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) - { - if( ctx->unprocessed_len != 0 ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) - { - int ret = 0; - - if( MBEDTLS_ENCRYPT == ctx->operation ) - { - /* check for 'no padding' mode */ - if( NULL == ctx->add_padding ) - { - if( 0 != ctx->unprocessed_len ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - - ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), - ctx->unprocessed_len ); - } - else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) - { - /* - * For decrypt operations, expect a full block, - * or an empty block if no padding - */ - if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) - return( 0 ); - - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - } - - /* cipher block */ - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - /* Set output size for decryption */ - if( MBEDTLS_DECRYPT == ctx->operation ) - return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), - olen ) ); - - /* Set output size for encryption */ - *olen = mbedtls_cipher_get_block_size( ctx ); - return( 0 ); - } -#else - ((void) output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, - mbedtls_cipher_padding_t mode ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - - if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto knows about CBC padding - * schemes, we currently don't make them - * accessible through the cipher layer. */ - if( mode != MBEDTLS_PADDING_NONE ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - switch( mode ) - { -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - case MBEDTLS_PADDING_PKCS7: - ctx->add_padding = add_pkcs_padding; - ctx->get_padding = get_pkcs_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) - case MBEDTLS_PADDING_ONE_AND_ZEROS: - ctx->add_padding = add_one_and_zeros_padding; - ctx->get_padding = get_one_and_zeros_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) - case MBEDTLS_PADDING_ZEROS_AND_LEN: - ctx->add_padding = add_zeros_and_len_padding; - ctx->get_padding = get_zeros_and_len_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) - case MBEDTLS_PADDING_ZEROS: - ctx->add_padding = add_zeros_padding; - ctx->get_padding = get_zeros_padding; - break; -#endif - case MBEDTLS_PADDING_NONE: - ctx->add_padding = NULL; - ctx->get_padding = get_no_padding; - break; - - default: - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_ENCRYPT != ctx->operation ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, - tag, tag_len ) ); -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != 16U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( mbedtls_chachapoly_finish( - (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) ); - } -#endif - - return( 0 ); -} - -int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len ) -{ - unsigned char check_tag[16]; - int ret; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_DECRYPT != ctx->operation ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - if( tag_len > sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( 0 != ( ret = mbedtls_gcm_finish( - (mbedtls_gcm_context *) ctx->cipher_ctx, - check_tag, tag_len ) ) ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - ret = mbedtls_chachapoly_finish( - (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag ); - if ( ret != 0 ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/* - * Packet-oriented wrapper for non-AEAD modes - */ -int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ) -{ - int ret; - size_t finish_olen; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; - size_t part_len; - - if( ctx->operation == MBEDTLS_DECRYPT ) - { - status = psa_cipher_decrypt_setup( &cipher_op, - cipher_psa->slot, - cipher_psa->alg ); - } - else if( ctx->operation == MBEDTLS_ENCRYPT ) - { - status = psa_cipher_encrypt_setup( &cipher_op, - cipher_psa->slot, - cipher_psa->alg ); - } - else - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* In the following, we can immediately return on an error, - * because the PSA Crypto API guarantees that cipher operations - * are terminated by unsuccessful calls to psa_cipher_update(), - * and by any call to psa_cipher_finish(). */ - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - status = psa_cipher_set_iv( &cipher_op, iv, iv_len ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - status = psa_cipher_update( &cipher_op, - input, ilen, - output, ilen, olen ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - status = psa_cipher_finish( &cipher_op, - output + *olen, ilen - *olen, - &part_len ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - *olen += part_len; - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_update( ctx, input, ilen, - output, olen ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, - &finish_olen ) ) != 0 ) - return( ret ); - - *olen += finish_olen; - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/* - * Packet-oriented encryption for AEAD modes - */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - - /* PSA Crypto API always writes the authentication tag - * at the end of the encrypted message. */ - if( tag != output + ilen ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - status = psa_aead_encrypt( cipher_psa->slot, - cipher_psa->alg, - iv, iv_len, - ad, ad_len, - input, ilen, - output, ilen + tag_len, olen ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - *olen -= tag_len; - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, - ilen, iv, iv_len, ad, ad_len, - input, output, tag_len, tag ) ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, input, output, - tag, tag_len ) ); - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, - ilen, iv, ad, ad_len, input, output, tag ) ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_NIST_KW_C) - if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || - MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) - { - mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? - MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - - /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ - if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); - } -#endif /* MBEDTLS_NIST_KW_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -/* - * Packet-oriented decryption for AEAD modes - */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ctx->psa_enabled == 1 ) - { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - - /* PSA Crypto API always writes the authentication tag - * at the end of the encrypted message. */ - if( tag != input + ilen ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - status = psa_aead_decrypt( cipher_psa->slot, - cipher_psa->alg, - iv, iv_len, - ad, ad_len, - input, ilen + tag_len, - output, ilen, olen ); - if( status == PSA_ERROR_INVALID_SIGNATURE ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - else if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - tag, tag_len, input, output ); - - if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - input, output, tag, tag_len ); - - if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int ret; - - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, - iv, ad, ad_len, tag, input, output ); - - if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_NIST_KW_C) - if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || - MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) - { - mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? - MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - - /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ - if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); - } -#endif /* MBEDTLS_NIST_KW_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c deleted file mode 100644 index 7fc40b5f0c..0000000000 --- a/library/cipher_wrap.c +++ /dev/null @@ -1,2411 +0,0 @@ -/** - * \file cipher_wrap.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "mbedtls/cipher_internal.h" - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#endif - -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_BLOWFISH_C) -#include "mbedtls/blowfish.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_NIST_KW_C) -#include "mbedtls/nist_kw.h" -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#include -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_GCM_C) -/* shared by all GCM ciphers */ -static void *gcm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); - - if( ctx != NULL ) - mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); - - return( ctx ); -} - -static void gcm_ctx_free( void *ctx ) -{ - mbedtls_gcm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -/* shared by all CCM ciphers */ -static void *ccm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); - - if( ctx != NULL ) - mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); - - return( ctx ); -} - -static void ccm_ctx_free( void *ctx ) -{ - mbedtls_ccm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_AES_C) - -static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off, - iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, - stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - int mode; - - switch( operation ) - { - case MBEDTLS_ENCRYPT: - mode = MBEDTLS_AES_ENCRYPT; - break; - case MBEDTLS_DECRYPT: - mode = MBEDTLS_AES_DECRYPT; - break; - default: - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return mbedtls_aes_crypt_xts( xts_ctx, mode, length, - data_unit, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static void * aes_ctx_alloc( void ) -{ - mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); - - if( aes == NULL ) - return( NULL ); - - mbedtls_aes_init( aes ); - - return( aes ); -} - -static void aes_ctx_free( void *ctx ) -{ - mbedtls_aes_free( (mbedtls_aes_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t aes_info = { - MBEDTLS_CIPHER_ID_AES, - aes_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aes_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aes_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - aes_crypt_ofb_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aes_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aes_setkey_enc_wrap, - aes_setkey_dec_wrap, - aes_ctx_alloc, - aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_ecb_info = { - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "AES-128-ECB", - 0, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ecb_info = { - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "AES-192-ECB", - 0, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ecb_info = { - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "AES-256-ECB", - 0, - 0, - 16, - &aes_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aes_128_cbc_info = { - MBEDTLS_CIPHER_AES_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "AES-128-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cbc_info = { - MBEDTLS_CIPHER_AES_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "AES-192-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cbc_info = { - MBEDTLS_CIPHER_AES_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "AES-256-CBC", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aes_128_cfb128_info = { - MBEDTLS_CIPHER_AES_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "AES-128-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cfb128_info = { - MBEDTLS_CIPHER_AES_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "AES-192-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cfb128_info = { - MBEDTLS_CIPHER_AES_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "AES-256-CFB128", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static const mbedtls_cipher_info_t aes_128_ofb_info = { - MBEDTLS_CIPHER_AES_128_OFB, - MBEDTLS_MODE_OFB, - 128, - "AES-128-OFB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ofb_info = { - MBEDTLS_CIPHER_AES_192_OFB, - MBEDTLS_MODE_OFB, - 192, - "AES-192-OFB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ofb_info = { - MBEDTLS_CIPHER_AES_256_OFB, - MBEDTLS_MODE_OFB, - 256, - "AES-256-OFB", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aes_128_ctr_info = { - MBEDTLS_CIPHER_AES_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "AES-128-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ctr_info = { - MBEDTLS_CIPHER_AES_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "AES-192-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ctr_info = { - MBEDTLS_CIPHER_AES_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "AES-256-CTR", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) ); -} - -static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) ); -} - -static void *xts_aes_ctx_alloc( void ) -{ - mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) ); - - if( xts_ctx != NULL ) - mbedtls_aes_xts_init( xts_ctx ); - - return( xts_ctx ); -} - -static void xts_aes_ctx_free( void *ctx ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - - if( xts_ctx == NULL ) - return; - - mbedtls_aes_xts_free( xts_ctx ); - mbedtls_free( xts_ctx ); -} - -static const mbedtls_cipher_base_t xts_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - aes_crypt_xts_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - xts_aes_setkey_enc_wrap, - xts_aes_setkey_dec_wrap, - xts_aes_ctx_alloc, - xts_aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_xts_info = { - MBEDTLS_CIPHER_AES_128_XTS, - MBEDTLS_MODE_XTS, - 256, - "AES-128-XTS", - 16, - 0, - 16, - &xts_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_xts_info = { - MBEDTLS_CIPHER_AES_256_XTS, - MBEDTLS_MODE_XTS, - 512, - "AES-256-XTS", - 16, - 0, - 16, - &xts_aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aes_setkey_wrap, - gcm_aes_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_gcm_info = { - MBEDTLS_CIPHER_AES_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "AES-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_gcm_info = { - MBEDTLS_CIPHER_AES_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "AES-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_gcm_info = { - MBEDTLS_CIPHER_AES_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "AES-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aes_setkey_wrap, - ccm_aes_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_ccm_info = { - MBEDTLS_CIPHER_AES_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "AES-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ccm_info = { - MBEDTLS_CIPHER_AES_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "AES-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ccm_info = { - MBEDTLS_CIPHER_AES_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "AES-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - -static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static void * camellia_ctx_alloc( void ) -{ - mbedtls_camellia_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_camellia_init( ctx ); - - return( ctx ); -} - -static void camellia_ctx_free( void *ctx ) -{ - mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - camellia_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - camellia_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - camellia_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - camellia_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - camellia_setkey_enc_wrap, - camellia_setkey_dec_wrap, - camellia_ctx_alloc, - camellia_ctx_free -}; - -static const mbedtls_cipher_info_t camellia_128_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "CAMELLIA-128-ECB", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "CAMELLIA-192-ECB", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "CAMELLIA-256-ECB", - 16, - 0, - 16, - &camellia_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t camellia_128_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "CAMELLIA-128-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "CAMELLIA-192-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "CAMELLIA-256-CBC", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t camellia_128_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "CAMELLIA-128-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "CAMELLIA-192-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "CAMELLIA-256-CFB128", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t camellia_128_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "CAMELLIA-128-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "CAMELLIA-192-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "CAMELLIA-256-CTR", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_camellia_setkey_wrap, - gcm_camellia_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "CAMELLIA-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "CAMELLIA-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "CAMELLIA-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_camellia_setkey_wrap, - ccm_camellia_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "CAMELLIA-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "CAMELLIA-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "CAMELLIA-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - -static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - (void) operation; - return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen ); -} - -static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen ); -} - -static void * aria_ctx_alloc( void ) -{ - mbedtls_aria_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_aria_init( ctx ); - - return( ctx ); -} - -static void aria_ctx_free( void *ctx ) -{ - mbedtls_aria_free( (mbedtls_aria_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - aria_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aria_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aria_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aria_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aria_setkey_enc_wrap, - aria_setkey_dec_wrap, - aria_ctx_alloc, - aria_ctx_free -}; - -static const mbedtls_cipher_info_t aria_128_ecb_info = { - MBEDTLS_CIPHER_ARIA_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "ARIA-128-ECB", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ecb_info = { - MBEDTLS_CIPHER_ARIA_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "ARIA-192-ECB", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ecb_info = { - MBEDTLS_CIPHER_ARIA_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "ARIA-256-ECB", - 16, - 0, - 16, - &aria_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aria_128_cbc_info = { - MBEDTLS_CIPHER_ARIA_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "ARIA-128-CBC", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_cbc_info = { - MBEDTLS_CIPHER_ARIA_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "ARIA-192-CBC", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_cbc_info = { - MBEDTLS_CIPHER_ARIA_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "ARIA-256-CBC", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aria_128_cfb128_info = { - MBEDTLS_CIPHER_ARIA_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "ARIA-128-CFB128", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_cfb128_info = { - MBEDTLS_CIPHER_ARIA_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "ARIA-192-CFB128", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_cfb128_info = { - MBEDTLS_CIPHER_ARIA_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "ARIA-256-CFB128", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aria_128_ctr_info = { - MBEDTLS_CIPHER_ARIA_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "ARIA-128-CTR", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ctr_info = { - MBEDTLS_CIPHER_ARIA_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "ARIA-192-CTR", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ctr_info = { - MBEDTLS_CIPHER_ARIA_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "ARIA-256-CTR", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aria_setkey_wrap, - gcm_aria_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_gcm_info = { - MBEDTLS_CIPHER_ARIA_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "ARIA-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; - -static const mbedtls_cipher_info_t aria_192_gcm_info = { - MBEDTLS_CIPHER_ARIA_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "ARIA-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; - -static const mbedtls_cipher_info_t aria_256_gcm_info = { - MBEDTLS_CIPHER_ARIA_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "ARIA-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aria_setkey_wrap, - ccm_aria_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_ccm_info = { - MBEDTLS_CIPHER_ARIA_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "ARIA-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ccm_info = { - MBEDTLS_CIPHER_ARIA_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "ARIA-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ccm_info = { - MBEDTLS_CIPHER_ARIA_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "ARIA-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - -static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); -} - -static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); -} - -static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); -} - -static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static void * des_ctx_alloc( void ) -{ - mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); - - if( des == NULL ) - return( NULL ); - - mbedtls_des_init( des ); - - return( des ); -} - -static void des_ctx_free( void *ctx ) -{ - mbedtls_des_free( (mbedtls_des_context *) ctx ); - mbedtls_free( ctx ); -} - -static void * des3_ctx_alloc( void ) -{ - mbedtls_des3_context *des3; - des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); - - if( des3 == NULL ) - return( NULL ); - - mbedtls_des3_init( des3 ); - - return( des3 ); -} - -static void des3_ctx_free( void *ctx ) -{ - mbedtls_des3_free( (mbedtls_des3_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t des_info = { - MBEDTLS_CIPHER_ID_DES, - des_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des_setkey_enc_wrap, - des_setkey_dec_wrap, - des_ctx_alloc, - des_ctx_free -}; - -static const mbedtls_cipher_info_t des_ecb_info = { - MBEDTLS_CIPHER_DES_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES, - "DES-ECB", - 8, - 0, - 8, - &des_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_cbc_info = { - MBEDTLS_CIPHER_DES_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES, - "DES-CBC", - 8, - 0, - 8, - &des_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede_info = { - MBEDTLS_CIPHER_ID_DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set2key_enc_wrap, - des3_set2key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede_ecb_info = { - MBEDTLS_CIPHER_DES_EDE_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-ECB", - 8, - 0, - 8, - &des_ede_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede_cbc_info = { - MBEDTLS_CIPHER_DES_EDE_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-CBC", - 8, - 0, - 8, - &des_ede_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede3_info = { - MBEDTLS_CIPHER_ID_3DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set3key_enc_wrap, - des3_set3key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede3_ecb_info = { - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-ECB", - 8, - 0, - 8, - &des_ede3_info -}; -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede3_cbc_info = { - MBEDTLS_CIPHER_DES_EDE3_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-CBC", - 8, - 0, - 8, - &des_ede3_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_BLOWFISH_C) - -static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, const unsigned char *input, - unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); -} - -static void * blowfish_ctx_alloc( void ) -{ - mbedtls_blowfish_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_blowfish_init( ctx ); - - return( ctx ); -} - -static void blowfish_ctx_free( void *ctx ) -{ - mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t blowfish_info = { - MBEDTLS_CIPHER_ID_BLOWFISH, - blowfish_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - blowfish_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - blowfish_crypt_cfb64_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - blowfish_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - blowfish_setkey_wrap, - blowfish_setkey_wrap, - blowfish_ctx_alloc, - blowfish_ctx_free -}; - -static const mbedtls_cipher_info_t blowfish_ecb_info = { - MBEDTLS_CIPHER_BLOWFISH_ECB, - MBEDTLS_MODE_ECB, - 128, - "BLOWFISH-ECB", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t blowfish_cbc_info = { - MBEDTLS_CIPHER_BLOWFISH_CBC, - MBEDTLS_MODE_CBC, - 128, - "BLOWFISH-CBC", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t blowfish_cfb64_info = { - MBEDTLS_CIPHER_BLOWFISH_CFB64, - MBEDTLS_MODE_CFB, - 128, - "BLOWFISH-CFB64", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t blowfish_ctr_info = { - MBEDTLS_CIPHER_BLOWFISH_CTR, - MBEDTLS_MODE_CTR, - 128, - "BLOWFISH-CTR", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_ARC4_C) -static int arc4_crypt_stream_wrap( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); -} - -static int arc4_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - /* we get key_bitlen in bits, arc4 expects it in bytes */ - if( key_bitlen % 8 != 0 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); - return( 0 ); -} - -static void * arc4_ctx_alloc( void ) -{ - mbedtls_arc4_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_arc4_init( ctx ); - - return( ctx ); -} - -static void arc4_ctx_free( void *ctx ) -{ - mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t arc4_base_info = { - MBEDTLS_CIPHER_ID_ARC4, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - arc4_crypt_stream_wrap, -#endif - arc4_setkey_wrap, - arc4_setkey_wrap, - arc4_ctx_alloc, - arc4_ctx_free -}; - -static const mbedtls_cipher_info_t arc4_128_info = { - MBEDTLS_CIPHER_ARC4_128, - MBEDTLS_MODE_STREAM, - 128, - "ARC4-128", - 0, - 0, - 1, - &arc4_base_info -}; -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CHACHA20_C) - -static int chacha20_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - if( key_bitlen != 256U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( 0 ); -} - -static int chacha20_stream_wrap( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - - ret = mbedtls_chacha20_update( ctx, length, input, output ); - if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( ret ); -} - -static void * chacha20_ctx_alloc( void ) -{ - mbedtls_chacha20_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_chacha20_init( ctx ); - - return( ctx ); -} - -static void chacha20_ctx_free( void *ctx ) -{ - mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t chacha20_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - chacha20_stream_wrap, -#endif - chacha20_setkey_wrap, - chacha20_setkey_wrap, - chacha20_ctx_alloc, - chacha20_ctx_free -}; -static const mbedtls_cipher_info_t chacha20_info = { - MBEDTLS_CIPHER_CHACHA20, - MBEDTLS_MODE_STREAM, - 256, - "CHACHA20", - 12, - 0, - 1, - &chacha20_base_info -}; -#endif /* MBEDTLS_CHACHA20_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - -static int chachapoly_setkey_wrap( void *ctx, - const unsigned char *key, - unsigned int key_bitlen ) -{ - if( key_bitlen != 256U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( 0 ); -} - -static void * chachapoly_ctx_alloc( void ) -{ - mbedtls_chachapoly_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_chachapoly_init( ctx ); - - return( ctx ); -} - -static void chachapoly_ctx_free( void *ctx ) -{ - mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t chachapoly_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - chachapoly_setkey_wrap, - chachapoly_setkey_wrap, - chachapoly_ctx_alloc, - chachapoly_ctx_free -}; -static const mbedtls_cipher_info_t chachapoly_info = { - MBEDTLS_CIPHER_CHACHA20_POLY1305, - MBEDTLS_MODE_CHACHAPOLY, - 256, - "CHACHA20-POLY1305", - 12, - 0, - 1, - &chachapoly_base_info -}; -#endif /* MBEDTLS_CHACHAPOLY_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -static int null_crypt_stream( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - ((void) ctx); - memmove( output, input, length ); - return( 0 ); -} - -static int null_setkey( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) ctx); - ((void) key); - ((void) key_bitlen); - - return( 0 ); -} - -static void * null_ctx_alloc( void ) -{ - return( (void *) 1 ); -} - -static void null_ctx_free( void *ctx ) -{ - ((void) ctx); -} - -static const mbedtls_cipher_base_t null_base_info = { - MBEDTLS_CIPHER_ID_NULL, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - null_crypt_stream, -#endif - null_setkey, - null_setkey, - null_ctx_alloc, - null_ctx_free -}; - -static const mbedtls_cipher_info_t null_cipher_info = { - MBEDTLS_CIPHER_NULL, - MBEDTLS_MODE_STREAM, - 0, - "NULL", - 0, - 0, - 1, - &null_base_info -}; -#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ - -#if defined(MBEDTLS_NIST_KW_C) -static void *kw_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) ); - - if( ctx != NULL ) - mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx ); - - return( ctx ); -} - -static void kw_ctx_free( void *ctx ) -{ - mbedtls_nist_kw_free( ctx ); - mbedtls_free( ctx ); -} - -static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx, - MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 ); -} - -static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx, - MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 ); -} - -static const mbedtls_cipher_base_t kw_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - kw_aes_setkey_wrap, - kw_aes_setkey_unwrap, - kw_ctx_alloc, - kw_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_nist_kw_info = { - MBEDTLS_CIPHER_AES_128_KW, - MBEDTLS_MODE_KW, - 128, - "AES-128-KW", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_nist_kw_info = { - MBEDTLS_CIPHER_AES_192_KW, - MBEDTLS_MODE_KW, - 192, - "AES-192-KW", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_nist_kw_info = { - MBEDTLS_CIPHER_AES_256_KW, - MBEDTLS_MODE_KW, - 256, - "AES-256-KW", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_128_nist_kwp_info = { - MBEDTLS_CIPHER_AES_128_KWP, - MBEDTLS_MODE_KWP, - 128, - "AES-128-KWP", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_nist_kwp_info = { - MBEDTLS_CIPHER_AES_192_KWP, - MBEDTLS_MODE_KWP, - 192, - "AES-192-KWP", - 0, - 0, - 16, - &kw_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_nist_kwp_info = { - MBEDTLS_CIPHER_AES_256_KWP, - MBEDTLS_MODE_KWP, - 256, - "AES-256-KWP", - 0, - 0, - 16, - &kw_aes_info -}; -#endif /* MBEDTLS_NIST_KW_C */ - -const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = -{ -#if defined(MBEDTLS_AES_C) - { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, - { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, - { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, - { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, - { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, - { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, - { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, - { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, - { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, - { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, - { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, - { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, - { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, - { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, - { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, - { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, -#endif -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_ARC4_C) - { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, -#endif - -#if defined(MBEDTLS_BLOWFISH_C) - { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, -#endif -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, -#endif -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info }, - { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info }, - { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info }, - { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info }, - { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info }, - { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info }, - { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info }, - { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info }, - { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info }, - { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info }, - { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info }, -#endif -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, -#endif -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_CHACHA20_C) - { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, -#endif - -#if defined(MBEDTLS_NIST_KW_C) - { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info }, - { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info }, - { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info }, - { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info }, - { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info }, - { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info }, -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - { MBEDTLS_CIPHER_NULL, &null_cipher_info }, -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - - { MBEDTLS_CIPHER_NONE, NULL } -}; - -#define NUM_CIPHERS ( sizeof(mbedtls_cipher_definitions) / \ - sizeof(mbedtls_cipher_definitions[0]) ) -int mbedtls_cipher_supported[NUM_CIPHERS]; - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/library/cmac.c b/library/cmac.c deleted file mode 100644 index 5d101e1c7d..0000000000 --- a/library/cmac.c +++ /dev/null @@ -1,1078 +0,0 @@ -/** - * \file cmac.c - * - * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * References: - * - * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The - * CMAC Mode for Authentication - * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf - * - * - RFC 4493 - The AES-CMAC Algorithm - * https://tools.ietf.org/html/rfc4493 - * - * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message - * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) - * Algorithm for the Internet Key Exchange Protocol (IKE) - * https://tools.ietf.org/html/rfc4615 - * - * Additional test vectors: ISO/IEC 9797-1 - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CMAC_C) - -#include "mbedtls/cmac.h" -#include "mbedtls/platform_util.h" - -#include - - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#if defined(MBEDTLS_SELF_TEST) -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_SELF_TEST */ -#endif /* MBEDTLS_PLATFORM_C */ - -#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) - -/* - * Multiplication by u in the Galois field of GF(2^n) - * - * As explained in NIST SP 800-38B, this can be computed: - * - * If MSB(p) = 0, then p = (p << 1) - * If MSB(p) = 1, then p = (p << 1) ^ R_n - * with R_64 = 0x1B and R_128 = 0x87 - * - * Input and output MUST NOT point to the same buffer - * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. - */ -static int cmac_multiply_by_u( unsigned char *output, - const unsigned char *input, - size_t blocksize ) -{ - const unsigned char R_128 = 0x87; - const unsigned char R_64 = 0x1B; - unsigned char R_n, mask; - unsigned char overflow = 0x00; - int i; - - if( blocksize == MBEDTLS_AES_BLOCK_SIZE ) - { - R_n = R_128; - } - else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE ) - { - R_n = R_64; - } - else - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - for( i = (int)blocksize - 1; i >= 0; i-- ) - { - output[i] = input[i] << 1 | overflow; - overflow = input[i] >> 7; - } - - /* mask = ( input[0] >> 7 ) ? 0xff : 0x00 - * using bit operations to avoid branches */ - - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - mask = - ( input[0] >> 7 ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - output[ blocksize - 1 ] ^= R_n & mask; - - return( 0 ); -} - -/* - * Generate subkeys - * - * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm - */ -static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, - unsigned char* K1, unsigned char* K2 ) -{ - int ret; - unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX]; - size_t olen, block_size; - - mbedtls_platform_zeroize( L, sizeof( L ) ); - - block_size = ctx->cipher_info->block_size; - - /* Calculate Ek(0) */ - if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 ) - goto exit; - - /* - * Generate K1 and K2 - */ - if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 ) - goto exit; - - if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 ) - goto exit; - -exit: - mbedtls_platform_zeroize( L, sizeof( L ) ); - - return( ret ); -} -#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */ - -#if !defined(MBEDTLS_CMAC_ALT) -static void cmac_xor_block( unsigned char *output, const unsigned char *input1, - const unsigned char *input2, - const size_t block_size ) -{ - size_t idx; - - for( idx = 0; idx < block_size; idx++ ) - output[ idx ] = input1[ idx ] ^ input2[ idx ]; -} - -/* - * Create padded last block from (partial) last block. - * - * We can't use the padding option from the cipher layer, as it only works for - * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. - */ -static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX], - size_t padded_block_len, - const unsigned char *last_block, - size_t last_block_len ) -{ - size_t j; - - for( j = 0; j < padded_block_len; j++ ) - { - if( j < last_block_len ) - padded_block[j] = last_block[j]; - else if( j == last_block_len ) - padded_block[j] = 0x80; - else - padded_block[j] = 0x00; - } -} - -int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, - const unsigned char *key, size_t keybits ) -{ - mbedtls_cipher_type_t type; - mbedtls_cmac_context_t *cmac_ctx; - int retval; - - if( ctx == NULL || ctx->cipher_info == NULL || key == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - return( retval ); - - type = ctx->cipher_info->type; - - switch( type ) - { - case MBEDTLS_CIPHER_AES_128_ECB: - case MBEDTLS_CIPHER_AES_192_ECB: - case MBEDTLS_CIPHER_AES_256_ECB: - case MBEDTLS_CIPHER_DES_EDE3_ECB: - break; - default: - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - /* Allocated and initialise in the cipher context memory for the CMAC - * context */ - cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) ); - if( cmac_ctx == NULL ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - - ctx->cmac_ctx = cmac_ctx; - - mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); - - return 0; -} - -int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, - const unsigned char *input, size_t ilen ) -{ - mbedtls_cmac_context_t* cmac_ctx; - unsigned char *state; - int ret = 0; - size_t n, j, olen, block_size; - - if( ctx == NULL || ctx->cipher_info == NULL || input == NULL || - ctx->cmac_ctx == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cmac_ctx = ctx->cmac_ctx; - block_size = ctx->cipher_info->block_size; - state = ctx->cmac_ctx->state; - - /* Is there data still to process from the last call, that's greater in - * size than a block? */ - if( cmac_ctx->unprocessed_len > 0 && - ilen > block_size - cmac_ctx->unprocessed_len ) - { - memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], - input, - block_size - cmac_ctx->unprocessed_len ); - - cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size ); - - if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, - &olen ) ) != 0 ) - { - goto exit; - } - - input += block_size - cmac_ctx->unprocessed_len; - ilen -= block_size - cmac_ctx->unprocessed_len; - cmac_ctx->unprocessed_len = 0; - } - - /* n is the number of blocks including any final partial block */ - n = ( ilen + block_size - 1 ) / block_size; - - /* Iterate across the input data in block sized chunks, excluding any - * final partial or complete block */ - for( j = 1; j < n; j++ ) - { - cmac_xor_block( state, input, state, block_size ); - - if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, - &olen ) ) != 0 ) - goto exit; - - ilen -= block_size; - input += block_size; - } - - /* If there is data left over that wasn't aligned to a block */ - if( ilen > 0 ) - { - memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], - input, - ilen ); - cmac_ctx->unprocessed_len += ilen; - } - -exit: - return( ret ); -} - -int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output ) -{ - mbedtls_cmac_context_t* cmac_ctx; - unsigned char *state, *last_block; - unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; - unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; - unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX]; - int ret; - size_t olen, block_size; - - if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || - output == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cmac_ctx = ctx->cmac_ctx; - block_size = ctx->cipher_info->block_size; - state = cmac_ctx->state; - - mbedtls_platform_zeroize( K1, sizeof( K1 ) ); - mbedtls_platform_zeroize( K2, sizeof( K2 ) ); - cmac_generate_subkeys( ctx, K1, K2 ); - - last_block = cmac_ctx->unprocessed_block; - - /* Calculate last block */ - if( cmac_ctx->unprocessed_len < block_size ) - { - cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len ); - cmac_xor_block( M_last, M_last, K2, block_size ); - } - else - { - /* Last block is complete block */ - cmac_xor_block( M_last, last_block, K1, block_size ); - } - - - cmac_xor_block( state, M_last, state, block_size ); - if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, - &olen ) ) != 0 ) - { - goto exit; - } - - memcpy( output, state, block_size ); - -exit: - /* Wipe the generated keys on the stack, and any other transients to avoid - * side channel leakage */ - mbedtls_platform_zeroize( K1, sizeof( K1 ) ); - mbedtls_platform_zeroize( K2, sizeof( K2 ) ); - - cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, - sizeof( cmac_ctx->unprocessed_block ) ); - - mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); - return( ret ); -} - -int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ) -{ - mbedtls_cmac_context_t* cmac_ctx; - - if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cmac_ctx = ctx->cmac_ctx; - - /* Reset the internal state */ - cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, - sizeof( cmac_ctx->unprocessed_block ) ); - mbedtls_platform_zeroize( cmac_ctx->state, - sizeof( cmac_ctx->state ) ); - - return( 0 ); -} - -int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - mbedtls_cipher_context_t ctx; - int ret; - - if( cipher_info == NULL || key == NULL || input == NULL || output == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - mbedtls_cipher_init( &ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) - goto exit; - - ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_cipher_cmac_update( &ctx, input, ilen ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_cipher_cmac_finish( &ctx, output ); - -exit: - mbedtls_cipher_free( &ctx ); - - return( ret ); -} - -#if defined(MBEDTLS_AES_C) -/* - * Implementation of AES-CMAC-PRF-128 defined in RFC 4615 - */ -int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, - const unsigned char *input, size_t in_len, - unsigned char *output ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; - unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; - - if( key == NULL || input == NULL || output == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB ); - if( cipher_info == NULL ) - { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto exit; - } - - if( key_length == MBEDTLS_AES_BLOCK_SIZE ) - { - /* Use key as is */ - memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); - } - else - { - memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); - - ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key, - key_length, int_key ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len, - output ); - -exit: - mbedtls_platform_zeroize( int_key, sizeof( int_key ) ); - - return( ret ); -} -#endif /* MBEDTLS_AES_C */ - -#endif /* !MBEDTLS_CMAC_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * CMAC test data for SP800-38B - * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf - * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf - * - * AES-CMAC-PRF-128 test data from RFC 4615 - * https://tools.ietf.org/html/rfc4615#page-4 - */ - -#define NB_CMAC_TESTS_PER_KEY 4 -#define NB_PRF_TESTS 3 - -#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) -/* All CMAC test inputs are truncated from the same 64 byte buffer. */ -static const unsigned char test_message[] = { - /* PT */ - 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, - 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, - 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, - 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 -}; -#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* Truncation point of message for AES CMAC tests */ -static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { - /* Mlen */ - 0, - 16, - 20, - 64 -}; - -/* CMAC-AES128 Test Data */ -static const unsigned char aes_128_key[16] = { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c -}; -static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, - 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde - }, - { - /* K2 */ - 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, - 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b - } -}; -static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* Example #1 */ - 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, - 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 - }, - { - /* Example #2 */ - 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, - 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c - }, - { - /* Example #3 */ - 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, - 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde - }, - { - /* Example #4 */ - 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, - 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe - } -}; - -/* CMAC-AES192 Test Data */ -static const unsigned char aes_192_key[24] = { - 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, - 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, - 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b -}; -static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, - 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 - }, - { - /* K2 */ - 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, - 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c - } -}; -static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* Example #1 */ - 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, - 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 - }, - { - /* Example #2 */ - 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, - 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 - }, - { - /* Example #3 */ - 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, - 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 - }, - { - /* Example #4 */ - 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, - 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 - } -}; - -/* CMAC-AES256 Test Data */ -static const unsigned char aes_256_key[32] = { - 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, - 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, - 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, - 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 -}; -static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, - 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f - }, - { - /* K2 */ - 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, - 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 - } -}; -static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* Example #1 */ - 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, - 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 - }, - { - /* Example #2 */ - 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, - 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c - }, - { - /* Example #3 */ - 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, - 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 - }, - { - /* Example #4 */ - 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, - 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 - } -}; -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_DES_C) -/* Truncation point of message for 3DES CMAC tests */ -static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { - 0, - 16, - 20, - 32 -}; - -/* CMAC-TDES (Generation) - 2 Key Test Data */ -static const unsigned char des3_2key_key[24] = { - /* Key1 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - /* Key2 */ - 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, - /* Key3 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef -}; -static const unsigned char des3_2key_subkeys[2][8] = { - { - /* K1 */ - 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 - }, - { - /* K2 */ - 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 - } -}; -static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { - { - /* Sample #1 */ - 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 - }, - { - /* Sample #2 */ - 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b - }, - { - /* Sample #3 */ - 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 - }, - { - /* Sample #4 */ - 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb - } -}; - -/* CMAC-TDES (Generation) - 3 Key Test Data */ -static const unsigned char des3_3key_key[24] = { - /* Key1 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, - /* Key2 */ - 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, - /* Key3 */ - 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 -}; -static const unsigned char des3_3key_subkeys[2][8] = { - { - /* K1 */ - 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 - }, - { - /* K2 */ - 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b - } -}; -static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { - { - /* Sample #1 */ - 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 - }, - { - /* Sample #2 */ - 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 - }, - { - /* Sample #3 */ - 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 - }, - { - /* Sample #4 */ - 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 - } -}; - -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* AES AES-CMAC-PRF-128 Test Data */ -static const unsigned char PRFK[] = { - /* Key */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0xed, 0xcb -}; - -/* Sizes in bytes */ -static const size_t PRFKlen[NB_PRF_TESTS] = { - 18, - 16, - 10 -}; - -/* Message */ -static const unsigned char PRFM[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 -}; - -static const unsigned char PRFT[NB_PRF_TESTS][16] = { - { - 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, - 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a - }, - { - 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, - 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d - }, - { - 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, - 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d - } -}; -#endif /* MBEDTLS_AES_C */ - -static int cmac_test_subkeys( int verbose, - const char* testname, - const unsigned char* key, - int keybits, - const unsigned char* subkeys, - mbedtls_cipher_type_t cipher_type, - int block_size, - int num_tests ) -{ - int i, ret = 0; - mbedtls_cipher_context_t ctx; - const mbedtls_cipher_info_t *cipher_info; - unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; - unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; - - cipher_info = mbedtls_cipher_info_from_type( cipher_type ); - if( cipher_info == NULL ) - { - /* Failing at this point must be due to a build issue */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - for( i = 0; i < num_tests; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 ); - - mbedtls_cipher_init( &ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "test execution failed\n" ); - - goto cleanup; - } - - if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "test execution failed\n" ); - - goto cleanup; - } - - ret = cmac_generate_subkeys( &ctx, K1, K2 ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 || - ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_cipher_free( &ctx ); - } - - ret = 0; - goto exit; - -cleanup: - mbedtls_cipher_free( &ctx ); - -exit: - return( ret ); -} - -static int cmac_test_wth_cipher( int verbose, - const char* testname, - const unsigned char* key, - int keybits, - const unsigned char* messages, - const unsigned int message_lengths[4], - const unsigned char* expected_result, - mbedtls_cipher_type_t cipher_type, - int block_size, - int num_tests ) -{ - const mbedtls_cipher_info_t *cipher_info; - int i, ret = 0; - unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; - - cipher_info = mbedtls_cipher_info_from_type( cipher_type ); - if( cipher_info == NULL ) - { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto exit; - } - - for( i = 0; i < num_tests; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 ); - - if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages, - message_lengths[i], output ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - - if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - ret = 0; - -exit: - return( ret ); -} - -#if defined(MBEDTLS_AES_C) -static int test_aes128_cmac_prf( int verbose ) -{ - int i; - int ret; - unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; - - for( i = 0; i < NB_PRF_TESTS; i++ ) - { - mbedtls_printf( " AES CMAC 128 PRF #%u: ", i ); - ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output ); - if( ret != 0 || - memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) - { - - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); - } - else if( verbose != 0 ) - { - mbedtls_printf( "passed\n" ); - } - } - return( ret ); -} -#endif /* MBEDTLS_AES_C */ - -int mbedtls_cmac_self_test( int verbose ) -{ - int ret; - -#if defined(MBEDTLS_AES_C) - /* AES-128 */ - if( ( ret = cmac_test_subkeys( verbose, - "AES 128", - aes_128_key, - 128, - (const unsigned char*)aes_128_subkeys, - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "AES 128", - aes_128_key, - 128, - test_message, - aes_message_lengths, - (const unsigned char*)aes_128_expected_result, - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - /* AES-192 */ - if( ( ret = cmac_test_subkeys( verbose, - "AES 192", - aes_192_key, - 192, - (const unsigned char*)aes_192_subkeys, - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "AES 192", - aes_192_key, - 192, - test_message, - aes_message_lengths, - (const unsigned char*)aes_192_expected_result, - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - /* AES-256 */ - if( ( ret = cmac_test_subkeys( verbose, - "AES 256", - aes_256_key, - 256, - (const unsigned char*)aes_256_subkeys, - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher ( verbose, - "AES 256", - aes_256_key, - 256, - test_message, - aes_message_lengths, - (const unsigned char*)aes_256_expected_result, - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_DES_C) - /* 3DES 2 key */ - if( ( ret = cmac_test_subkeys( verbose, - "3DES 2 key", - des3_2key_key, - 192, - (const unsigned char*)des3_2key_subkeys, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "3DES 2 key", - des3_2key_key, - 192, - test_message, - des3_message_lengths, - (const unsigned char*)des3_2key_expected_result, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - /* 3DES 3 key */ - if( ( ret = cmac_test_subkeys( verbose, - "3DES 3 key", - des3_3key_key, - 192, - (const unsigned char*)des3_3key_subkeys, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "3DES 3 key", - des3_3key_key, - 192, - test_message, - des3_message_lengths, - (const unsigned char*)des3_3key_expected_result, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 ) - return( ret ); -#endif /* MBEDTLS_AES_C */ - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CMAC_C */ diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c deleted file mode 100644 index 0db7beb29d..0000000000 --- a/library/ctr_drbg.c +++ /dev/null @@ -1,751 +0,0 @@ -/* - * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The NIST SP 800-90 DRBGs are described in the following publication. - * - * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) - -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -/* - * CTR_DRBG context initialization - */ -void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif -} - -/* - * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow - * NIST tests to succeed (which require known length fixed entropy) - */ -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy, - * custom, len, entropy_len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * custom[:len] = nonce || personalization_string - * where entropy_input comes from f_entropy for entropy_len bytes - * and with outputs - * ctx = initial_working_state - */ -int mbedtls_ctr_drbg_seed_entropy_len( - mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len, - size_t entropy_len ) -{ - int ret; - unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; - - memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); - - mbedtls_aes_init( &ctx->aes_ctx ); - - ctx->f_entropy = f_entropy; - ctx->p_entropy = p_entropy; - - ctx->entropy_len = entropy_len; - ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; - - /* - * Initialize with an empty key - */ - if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, - MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) - { - return( ret ); - } - return( 0 ); -} - -int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len ) -{ - return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, - custom, len, - MBEDTLS_CTR_DRBG_ENTROPY_LEN ) ); -} - -void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif - mbedtls_aes_free( &ctx->aes_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); -} - -void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, - int resistance ) -{ - ctx->prediction_resistance = resistance; -} - -void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, - size_t len ) -{ - ctx->entropy_len = len; -} - -void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, - int interval ) -{ - ctx->reseed_interval = interval; -} - -static int block_cipher_df( unsigned char *output, - const unsigned char *data, size_t data_len ) -{ - unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + - MBEDTLS_CTR_DRBG_BLOCKSIZE + 16]; - unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; - unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; - unsigned char *p, *iv; - mbedtls_aes_context aes_ctx; - int ret = 0; - - int i, j; - size_t buf_len, use_len; - - if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) - return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - - memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + - MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 ); - mbedtls_aes_init( &aes_ctx ); - - /* - * Construct IV (16 bytes) and S in buffer - * IV = Counter (in 32-bits) padded to 16 with zeroes - * S = Length input string (in 32-bits) || Length of output (in 32-bits) || - * data || 0x80 - * (Total is padded to a multiple of 16-bytes with zeroes) - */ - p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE; - *p++ = ( data_len >> 24 ) & 0xff; - *p++ = ( data_len >> 16 ) & 0xff; - *p++ = ( data_len >> 8 ) & 0xff; - *p++ = ( data_len ) & 0xff; - p += 3; - *p++ = MBEDTLS_CTR_DRBG_SEEDLEN; - memcpy( p, data, data_len ); - p[data_len] = 0x80; - - buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; - - for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ ) - key[i] = i; - - if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, - MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - goto exit; - } - - /* - * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data - */ - for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) - { - p = buf; - memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE ); - use_len = buf_len; - - while( use_len > 0 ) - { - for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ ) - chain[i] ^= p[i]; - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? - MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; - - if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, - chain, chain ) ) != 0 ) - { - goto exit; - } - } - - memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); - - /* - * Update IV - */ - buf[3]++; - } - - /* - * Do final encryption with reduced data - */ - if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, - MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - goto exit; - } - iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; - p = output; - - for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) - { - if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, - iv, iv ) ) != 0 ) - { - goto exit; - } - memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - } -exit: - mbedtls_aes_free( &aes_ctx ); - /* - * tidy up the stack - */ - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_platform_zeroize( chain, sizeof( chain ) ); - if( 0 != ret ) - { - /* - * wipe partial seed from memory - */ - mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN ); - } - - return( ret ); -} - -/* CTR_DRBG_Update (SP 800-90A §10.2.1.2) - * ctr_drbg_update_internal(ctx, provided_data) - * implements - * CTR_DRBG_Update(provided_data, Key, V) - * with inputs and outputs - * ctx->aes_ctx = Key - * ctx->counter = V - */ -static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, - const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] ) -{ - unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char *p = tmp; - int i, j; - int ret = 0; - - memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); - - for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) - { - /* - * Increase counter - */ - for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) - if( ++ctx->counter[i - 1] != 0 ) - break; - - /* - * Crypt counter block - */ - if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, - ctx->counter, p ) ) != 0 ) - { - goto exit; - } - - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - } - - for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ ) - tmp[i] ^= data[i]; - - /* - * Update key and counter - */ - if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, - MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - goto exit; - } - memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, - MBEDTLS_CTR_DRBG_BLOCKSIZE ); - -exit: - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - return( ret ); -} - -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_update(ctx, additional, add_len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * ctx->counter = all-bits-0 - * ctx->aes_ctx = context from all-bits-0 key - * additional[:add_len] = entropy_input || nonce || personalization_string - * and with outputs - * ctx = initial_working_state - */ -int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; - int ret; - - if( add_len == 0 ) - return( 0 ); - - if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) - goto exit; - if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) - goto exit; - -exit: - mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - /* MAX_INPUT would be more logical here, but we have to match - * block_cipher_df()'s limits since we can't propagate errors */ - if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) - add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; - (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len ); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2) - * mbedtls_ctr_drbg_reseed(ctx, additional, len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional_input) - * -> new_working_state - * with inputs - * ctx contains working_state - * additional[:len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * and with output - * ctx contains new_working_state - */ -int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, size_t len ) -{ - unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; - size_t seedlen = 0; - int ret; - - if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || - len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) - return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - - memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); - - /* - * Gather entropy_len bytes of entropy to seed state - */ - if( 0 != ctx->f_entropy( ctx->p_entropy, seed, - ctx->entropy_len ) ) - { - return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); - } - - seedlen += ctx->entropy_len; - - /* - * Add additional data - */ - if( additional && len ) - { - memcpy( seed + seedlen, additional, len ); - seedlen += len; - } - - /* - * Reduce to 384 bits - */ - if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 ) - goto exit; - - /* - * Update state - */ - if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 ) - goto exit; - ctx->reseed_counter = 1; - -exit: - mbedtls_platform_zeroize( seed, sizeof( seed ) ); - return( ret ); -} - -/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2) - * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len]) - * -> working_state_after_reseed - * if required, then - * CTR_DRBG_Generate(working_state_after_reseed, - * requested_number_of_bits, additional_input) - * -> status, returned_bits, new_working_state - * with inputs - * ctx contains working_state - * requested_number_of_bits = 8 * output_len - * additional[:add_len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * and with outputs - * status = SUCCESS (this function does the reseed internally) - * returned_bits = output[:output_len] - * ctx contains new_working_state - */ -int mbedtls_ctr_drbg_random_with_add( void *p_rng, - unsigned char *output, size_t output_len, - const unsigned char *additional, size_t add_len ) -{ - int ret = 0; - mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; - unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char *p = output; - unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; - int i; - size_t use_len; - - if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST ) - return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG ); - - if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT ) - return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - - memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); - - if( ctx->reseed_counter > ctx->reseed_interval || - ctx->prediction_resistance ) - { - if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) - { - return( ret ); - } - add_len = 0; - } - - if( add_len > 0 ) - { - if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) - goto exit; - if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) - goto exit; - } - - while( output_len > 0 ) - { - /* - * Increase counter - */ - for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) - if( ++ctx->counter[i - 1] != 0 ) - break; - - /* - * Crypt counter block - */ - if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, - ctx->counter, tmp ) ) != 0 ) - { - goto exit; - } - - use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) - ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len; - /* - * Copy random block to destination - */ - memcpy( p, tmp, use_len ); - p += use_len; - output_len -= use_len; - } - - if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) - goto exit; - - ctx->reseed_counter++; - -exit: - mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - return( 0 ); -} - -int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, - size_t output_len ) -{ - int ret; - mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, - const char *path ) -{ - int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - FILE *f; - unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; - - if( ( f = fopen( path, "wb" ) ) == NULL ) - return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); - - if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, - MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 ) - goto exit; - - if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != - MBEDTLS_CTR_DRBG_MAX_INPUT ) - { - ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - } - else - { - ret = 0; - } - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - fclose( f ); - return( ret ); -} - -int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, - const char *path ) -{ - int ret = 0; - FILE *f = NULL; - size_t n; - unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; - unsigned char c; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); - - n = fread( buf, 1, sizeof( buf ), f ); - if( fread( &c, 1, 1, f ) != 0 ) - { - ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - goto exit; - } - if( n == 0 || ferror( f ) ) - { - ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - goto exit; - } - fclose( f ); - f = NULL; - - ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n ); - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - if( f != NULL ) - fclose( f ); - if( ret != 0 ) - return( ret ); - return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char entropy_source_pr[96] = - { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, - 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, - 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, - 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, - 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, - 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, - 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, - 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, - 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, - 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, - 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, - 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; - -static const unsigned char entropy_source_nopr[64] = - { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, - 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, - 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, - 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, - 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, - 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, - 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, - 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; - -static const unsigned char nonce_pers_pr[16] = - { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, - 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; - -static const unsigned char nonce_pers_nopr[16] = - { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, - 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; - -static const unsigned char result_pr[16] = - { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, - 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; - -static const unsigned char result_nopr[16] = - { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, - 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; - -static size_t test_offset; -static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, - size_t len ) -{ - const unsigned char *p = data; - memcpy( buf, p + test_offset, len ); - test_offset += len; - return( 0 ); -} - -#define CHK( c ) if( (c) != 0 ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf( "failed\n" ); \ - return( 1 ); \ - } - -/* - * Checkup routine - */ -int mbedtls_ctr_drbg_self_test( int verbose ) -{ - mbedtls_ctr_drbg_context ctx; - unsigned char buf[16]; - - mbedtls_ctr_drbg_init( &ctx ); - - /* - * Based on a NIST CTR_DRBG test vector (PR = True) - */ - if( verbose != 0 ) - mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); - - test_offset = 0; - CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, - (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) ); - mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); - CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); - - mbedtls_ctr_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - /* - * Based on a NIST CTR_DRBG test vector (PR = FALSE) - */ - if( verbose != 0 ) - mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); - - mbedtls_ctr_drbg_init( &ctx ); - - test_offset = 0; - CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, - (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); - CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); - CHK( memcmp( buf, result_nopr, 16 ) ); - - mbedtls_ctr_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CTR_DRBG_C */ diff --git a/library/des.c b/library/des.c deleted file mode 100644 index 8a33d82e50..0000000000 --- a/library/des.c +++ /dev/null @@ -1,1064 +0,0 @@ -/* - * FIPS-46-3 compliant Triple-DES implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * 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). - * - * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_DES_C) - -#include "mbedtls/des.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_DES_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * 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 ) -{ - memset( ctx, 0, sizeof( mbedtls_des_context ) ); -} - -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 ) -{ - memset( ctx, 0, sizeof( mbedtls_des3_context ) ); -} - -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++ ) - if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 ) - 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, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) -{ - 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, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) -{ - 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, - const unsigned char input[8], - unsigned char output[8] ) -{ - 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, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output ) -{ - 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, - const unsigned char input[8], - unsigned char output[8] ) -{ - 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, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output ) -{ - 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 */ - -#endif /* !MBEDTLS_DES_ALT */ - -#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] = -{ - { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, - { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, - { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } -}; - -static const unsigned char des3_test_ecb_enc[3][8] = -{ - { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, - { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, - { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } -}; - -#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] = -{ - { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, - { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, - { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } -}; - -static const unsigned char des3_test_cbc_enc[3][8] = -{ - { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, - { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, - { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/* - * Checkup routine - */ -int mbedtls_des_self_test( int verbose ) -{ - int i, j, u, v, ret = 0; - mbedtls_des_context ctx; - mbedtls_des3_context ctx3; - unsigned char buf[8]; -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[8]; - unsigned char iv[8]; -#endif - - mbedtls_des_init( &ctx ); - mbedtls_des3_init( &ctx3 ); - /* - * 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: - mbedtls_des_setkey_dec( &ctx, des3_test_keys ); - break; - - case 1: - mbedtls_des_setkey_enc( &ctx, des3_test_keys ); - break; - - case 2: - mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); - break; - - case 3: - mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); - break; - - case 4: - mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); - break; - - case 5: - mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); - break; - - default: - return( 1 ); - } - - for( j = 0; j < 10000; j++ ) - { - if( u == 0 ) - mbedtls_des_crypt_ecb( &ctx, buf, buf ); - else - mbedtls_des3_crypt_ecb( &ctx3, buf, buf ); - } - - if( ( v == MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || - ( v != MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) - { - 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: - mbedtls_des_setkey_dec( &ctx, des3_test_keys ); - break; - - case 1: - mbedtls_des_setkey_enc( &ctx, des3_test_keys ); - break; - - case 2: - mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); - break; - - case 3: - mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); - break; - - case 4: - mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); - break; - - case 5: - mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); - break; - - default: - return( 1 ); - } - - if( v == MBEDTLS_DES_DECRYPT ) - { - for( j = 0; j < 10000; j++ ) - { - if( u == 0 ) - mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); - else - mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); - } - } - else - { - for( j = 0; j < 10000; j++ ) - { - unsigned char tmp[8]; - - if( u == 0 ) - mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); - else - mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); - - memcpy( tmp, prv, 8 ); - memcpy( prv, buf, 8 ); - memcpy( buf, tmp, 8 ); - } - - memcpy( buf, prv, 8 ); - } - - if( ( v == MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || - ( v != MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) - { - 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: - mbedtls_des_free( &ctx ); - mbedtls_des3_free( &ctx3 ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_DES_C */ diff --git a/library/dhm.c b/library/dhm.c deleted file mode 100644 index 8255632a99..0000000000 --- a/library/dhm.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Diffie-Hellman-Merkle key exchange - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The following sources were referenced in the design of this implementation - * of the Diffie-Hellman-Merkle algorithm: - * - * [1] Handbook of Applied Cryptography - 1997, Chapter 12 - * Menezes, van Oorschot and Vanstone - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_DHM_C) - -#include "mbedtls/dhm.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if !defined(MBEDTLS_DHM_ALT) - -#define DHM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA ) -#define DHM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * helper to validate the mbedtls_mpi size and import it - */ -static int dhm_read_bignum( mbedtls_mpi *X, - unsigned char **p, - const unsigned char *end ) -{ - int ret, n; - - if( end - *p < 2 ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - n = ( (*p)[0] << 8 ) | (*p)[1]; - (*p) += 2; - - if( (int)( end - *p ) < n ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 ) - return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret ); - - (*p) += n; - - return( 0 ); -} - -/* - * Verify sanity of parameter with regards to P - * - * Parameter should be: 2 <= public_param <= P - 2 - * - * This means that we need to return an error if - * public_param < 2 or public_param > P-2 - * - * For more information on the attack, see: - * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf - * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 - */ -static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P ) -{ - mbedtls_mpi L, U; - int ret = 0; - - mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) ); - - if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 || - mbedtls_mpi_cmp_mpi( param, &U ) > 0 ) - { - ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - -cleanup: - mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U ); - return( ret ); -} - -void mbedtls_dhm_init( mbedtls_dhm_context *ctx ) -{ - DHM_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_dhm_context ) ); -} - -/* - * Parse the ServerKeyExchange parameters - */ -int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, - unsigned char **p, - const unsigned char *end ) -{ - int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( p != NULL && *p != NULL ); - DHM_VALIDATE_RET( end != NULL ); - - if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 || - ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 || - ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 ) - return( ret ); - - if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) - return( ret ); - - ctx->len = mbedtls_mpi_size( &ctx->P ); - - return( 0 ); -} - -/* - * Setup and write the ServerKeyExchange parameters - */ -int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret, count = 0; - size_t n1, n2, n3; - unsigned char *p; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( olen != NULL ); - DHM_VALIDATE_RET( f_rng != NULL ); - - if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - /* - * Generate X as large as possible ( < P ) - */ - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) ); - - while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); - - if( count++ > 10 ) - return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED ); - } - while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); - - /* - * Calculate GX = G^X mod P - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, - &ctx->P , &ctx->RP ) ); - - if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) - return( ret ); - - /* - * export P, G, GX - */ -#define DHM_MPI_EXPORT( X, n ) \ - do { \ - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \ - p + 2, \ - ( n ) ) ); \ - *p++ = (unsigned char)( ( n ) >> 8 ); \ - *p++ = (unsigned char)( ( n ) ); \ - p += ( n ); \ - } while( 0 ) - - n1 = mbedtls_mpi_size( &ctx->P ); - n2 = mbedtls_mpi_size( &ctx->G ); - n3 = mbedtls_mpi_size( &ctx->GX ); - - p = output; - DHM_MPI_EXPORT( &ctx->P , n1 ); - DHM_MPI_EXPORT( &ctx->G , n2 ); - DHM_MPI_EXPORT( &ctx->GX, n3 ); - - *olen = p - output; - - ctx->len = n1; - -cleanup: - - if( ret != 0 ) - return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret ); - - return( 0 ); -} - -/* - * Set prime modulus and generator - */ -int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, - const mbedtls_mpi *P, - const mbedtls_mpi *G ) -{ - int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( P != NULL ); - DHM_VALIDATE_RET( G != NULL ); - - if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 || - ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 ) - { - return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret ); - } - - ctx->len = mbedtls_mpi_size( &ctx->P ); - return( 0 ); -} - -/* - * Import the peer's public value G^Y - */ -int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, - const unsigned char *input, size_t ilen ) -{ - int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( input != NULL ); - - if( ilen < 1 || ilen > ctx->len ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) - return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret ); - - return( 0 ); -} - -/* - * Create own private value X and export G^X - */ -int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret, count = 0; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( f_rng != NULL ); - - if( olen < 1 || olen > ctx->len ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - /* - * generate X and calculate GX = G^X mod P - */ - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) ); - - while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); - - if( count++ > 10 ) - return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED ); - } - while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, - &ctx->P , &ctx->RP ) ); - - if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) - return( ret ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) ); - -cleanup: - - if( ret != 0 ) - return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); - - return( 0 ); -} - -/* - * Use the blinding method and optimisation suggested in section 10 of: - * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, - * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer - * Berlin Heidelberg, 1996. p. 104-113. - */ -static int dhm_update_blinding( mbedtls_dhm_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret, count; - - /* - * Don't use any blinding the first time a particular X is used, - * but remember it to use blinding next time. - */ - if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) ); - - return( 0 ); - } - - /* - * Ok, we need blinding. Can we re-use existing values? - * If yes, just update them by squaring them. - */ - if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); - - return( 0 ); - } - - /* - * We need to generate blinding values from scratch - */ - - /* Vi = random( 2, P-1 ) */ - count = 0; - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) ); - - while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) ); - - if( count++ > 10 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - } - while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 ); - - /* Vf = Vi^-X mod P */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); - -cleanup: - return( ret ); -} - -/* - * Derive and export the shared secret (G^Y)^X mod P - */ -int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, - unsigned char *output, size_t output_size, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_mpi GYb; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( olen != NULL ); - - if( output_size < ctx->len ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) - return( ret ); - - mbedtls_mpi_init( &GYb ); - - /* Blind peer's value */ - if( f_rng != NULL ) - { - MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) ); - } - else - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) ); - - /* Do modular exponentiation */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X, - &ctx->P, &ctx->RP ) ); - - /* Unblind secret value */ - if( f_rng != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) ); - } - - *olen = mbedtls_mpi_size( &ctx->K ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) ); - -cleanup: - mbedtls_mpi_free( &GYb ); - - if( ret != 0 ) - return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret ); - - return( 0 ); -} - -/* - * Free the components of a DHM key - */ -void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->pX ); - mbedtls_mpi_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->Vi ); - mbedtls_mpi_free( &ctx->RP ); - mbedtls_mpi_free( &ctx->K ); - mbedtls_mpi_free( &ctx->GY ); - mbedtls_mpi_free( &ctx->GX ); - mbedtls_mpi_free( &ctx->X ); - mbedtls_mpi_free( &ctx->G ); - mbedtls_mpi_free( &ctx->P ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); -} - -#if defined(MBEDTLS_ASN1_PARSE_C) -/* - * Parse DHM parameters - */ -int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, - size_t dhminlen ) -{ - int ret; - size_t len; - unsigned char *p, *end; -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_context pem; -#endif /* MBEDTLS_PEM_PARSE_C */ - - DHM_VALIDATE_RET( dhm != NULL ); - DHM_VALIDATE_RET( dhmin != NULL ); - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN DH PARAMETERS-----", - "-----END DH PARAMETERS-----", - dhmin, NULL, 0, &dhminlen ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - dhminlen = pem.buflen; - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - goto exit; - - p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; -#else - p = (unsigned char *) dhmin; -#endif /* MBEDTLS_PEM_PARSE_C */ - end = p + dhminlen; - - /* - * DHParams ::= SEQUENCE { - * prime INTEGER, -- P - * generator INTEGER, -- g - * privateValueLength INTEGER OPTIONAL - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; - goto exit; - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; - goto exit; - } - - if( p != end ) - { - /* This might be the optional privateValueLength. - * If so, we can cleanly discard it */ - mbedtls_mpi rec; - mbedtls_mpi_init( &rec ); - ret = mbedtls_asn1_get_mpi( &p, end, &rec ); - mbedtls_mpi_free( &rec ); - if ( ret != 0 ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; - goto exit; - } - if ( p != end ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - goto exit; - } - } - - ret = 0; - - dhm->len = mbedtls_mpi_size( &dhm->P ); - -exit: -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_free( &pem ); -#endif - if( ret != 0 ) - mbedtls_dhm_free( dhm ); - - return( ret ); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load all data from a file into a given buffer. - * - * The file is expected to contain either PEM or DER encoded data. - * A terminating null byte is always appended. It is included in the announced - * length only if the data looks like it is PEM encoded. - */ -static int load_file( const char *path, unsigned char **buf, size_t *n ) -{ - FILE *f; - long size; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); - - fseek( f, 0, SEEK_END ); - if( ( size = ftell( f ) ) == -1 ) - { - fclose( f ); - return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); - } - fseek( f, 0, SEEK_SET ); - - *n = (size_t) size; - - if( *n + 1 == 0 || - ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) - { - fclose( f ); - return( MBEDTLS_ERR_DHM_ALLOC_FAILED ); - } - - if( fread( *buf, 1, *n, f ) != *n ) - { - fclose( f ); - - mbedtls_platform_zeroize( *buf, *n + 1 ); - mbedtls_free( *buf ); - - return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); - } - - fclose( f ); - - (*buf)[*n] = '\0'; - - if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) - ++*n; - - return( 0 ); -} - -/* - * Load and parse DHM parameters - */ -int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - DHM_VALIDATE_RET( dhm != NULL ); - DHM_VALIDATE_RET( path != NULL ); - - if( ( ret = load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_dhm_parse_dhm( dhm, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ -#endif /* MBEDTLS_ASN1_PARSE_C */ -#endif /* MBEDTLS_DHM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_PEM_PARSE_C) -static const char mbedtls_test_dhm_params[] = -"-----BEGIN DH PARAMETERS-----\r\n" -"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" -"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" -"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" -"-----END DH PARAMETERS-----\r\n"; -#else /* MBEDTLS_PEM_PARSE_C */ -static const char mbedtls_test_dhm_params[] = { - 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, - 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, - 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, - 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, - 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, - 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, - 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, - 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, - 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, - 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, - 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, - 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 }; -#endif /* MBEDTLS_PEM_PARSE_C */ - -static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); - -/* - * Checkup routine - */ -int mbedtls_dhm_self_test( int verbose ) -{ - int ret; - mbedtls_dhm_context dhm; - - mbedtls_dhm_init( &dhm ); - - if( verbose != 0 ) - mbedtls_printf( " DHM parameter load: " ); - - if( ( ret = mbedtls_dhm_parse_dhm( &dhm, - (const unsigned char *) mbedtls_test_dhm_params, - mbedtls_test_dhm_params_len ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n\n" ); - -exit: - mbedtls_dhm_free( &dhm ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_DHM_C */ diff --git a/library/ecdh.c b/library/ecdh.c deleted file mode 100644 index eecae91310..0000000000 --- a/library/ecdh.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * Elliptic curve Diffie-Hellman - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * References: - * - * SEC1 http://www.secg.org/index.php?action=secg,docs_secg - * RFC 4492 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECDH_C) - -#include "mbedtls/ecdh.h" -#include "mbedtls/platform_util.h" - -#include - -/* Parameter validation macros based on platform_util.h */ -#define ECDH_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECDH_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) -typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; -#endif - -static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( - const mbedtls_ecdh_context *ctx ) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ctx->grp.id ); -#else - return( ctx->grp_id ); -#endif -} - -#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) -/* - * Generate public key (restartable version) - * - * Note: this internal function relies on its caller preserving the value of - * the output parameter 'd' across continuation calls. This would not be - * acceptable for a public function but is OK here as we control call sites. - */ -static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - - /* If multiplication is in progress, we already generated a privkey */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx == NULL || rs_ctx->rsm == NULL ) -#endif - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G, - f_rng, p_rng, rs_ctx ) ); - -cleanup: - return( ret ); -} - -/* - * Generate public key - */ -int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECDH_VALIDATE_RET( grp != NULL ); - ECDH_VALIDATE_RET( d != NULL ); - ECDH_VALIDATE_RET( Q != NULL ); - ECDH_VALIDATE_RET( f_rng != NULL ); - return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) ); -} -#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */ - -#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) -/* - * Compute shared secret (SEC1 3.3.1) - */ -static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_ecp_point P; - - mbedtls_ecp_point_init( &P ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q, - f_rng, p_rng, rs_ctx ) ); - - if( mbedtls_ecp_is_zero( &P ) ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); - -cleanup: - mbedtls_ecp_point_free( &P ); - - return( ret ); -} - -/* - * Compute shared secret (SEC1 3.3.1) - */ -int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECDH_VALIDATE_RET( grp != NULL ); - ECDH_VALIDATE_RET( Q != NULL ); - ECDH_VALIDATE_RET( d != NULL ); - ECDH_VALIDATE_RET( z != NULL ); - return( ecdh_compute_shared_restartable( grp, z, Q, d, - f_rng, p_rng, NULL ) ); -} -#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ - -static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx ) -{ - mbedtls_ecp_group_init( &ctx->grp ); - mbedtls_mpi_init( &ctx->d ); - mbedtls_ecp_point_init( &ctx->Q ); - mbedtls_ecp_point_init( &ctx->Qp ); - mbedtls_mpi_init( &ctx->z ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_init( &ctx->rs ); -#endif -} - -/* - * Initialize context - */ -void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) -{ - ECDH_VALIDATE( ctx != NULL ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - ecdh_init_internal( ctx ); - mbedtls_ecp_point_init( &ctx->Vi ); - mbedtls_ecp_point_init( &ctx->Vf ); - mbedtls_mpi_init( &ctx->_d ); -#else - memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); - - ctx->var = MBEDTLS_ECDH_VARIANT_NONE; -#endif - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; -#if defined(MBEDTLS_ECP_RESTARTABLE) - ctx->restart_enabled = 0; -#endif -} - -static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx, - mbedtls_ecp_group_id grp_id ) -{ - int ret; - - ret = mbedtls_ecp_group_load( &ctx->grp, grp_id ); - if( ret != 0 ) - { - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} - -/* - * Setup context - */ -int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id ) -{ - ECDH_VALIDATE_RET( ctx != NULL ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_setup_internal( ctx, grp_id ) ); -#else - switch( grp_id ) - { - default: - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; - ctx->grp_id = grp_id; - ecdh_init_internal( &ctx->ctx.mbed_ecdh ); - return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) ); - } -#endif -} - -static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx ) -{ - mbedtls_ecp_group_free( &ctx->grp ); - mbedtls_mpi_free( &ctx->d ); - mbedtls_ecp_point_free( &ctx->Q ); - mbedtls_ecp_point_free( &ctx->Qp ); - mbedtls_mpi_free( &ctx->z ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_free( &ctx->rs ); -#endif -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Enable restartable operations for context - */ -void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ) -{ - ECDH_VALIDATE( ctx != NULL ); - - ctx->restart_enabled = 1; -} -#endif - -/* - * Free context - */ -void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_ecp_point_free( &ctx->Vi ); - mbedtls_ecp_point_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->_d ); - ecdh_free_internal( ctx ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - ecdh_free_internal( &ctx->ctx.mbed_ecdh ); - break; - default: - break; - } - - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - ctx->var = MBEDTLS_ECDH_VARIANT_NONE; - ctx->grp_id = MBEDTLS_ECP_DP_NONE; -#endif -} - -static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx, - size_t *olen, int point_format, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled ) -{ - int ret; - size_t grp_len, pt_len; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if( ctx->grp.pbits == 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( restart_enabled ) - rs_ctx = &ctx->rs; -#else - (void) restart_enabled; -#endif - - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng, rs_ctx ) ) != 0 ) - return( ret ); -#else - if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng ) ) != 0 ) - return( ret ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, - blen ) ) != 0 ) - return( ret ); - - buf += grp_len; - blen -= grp_len; - - if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, - &pt_len, buf, blen ) ) != 0 ) - return( ret ); - - *olen = grp_len + pt_len; - return( 0 ); -} - -/* - * Setup and write the ServerKeyExhange parameters (RFC 4492) - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ -int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int restart_enabled = 0; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( olen != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - ECDH_VALIDATE_RET( f_rng != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen, - f_rng, p_rng, restart_enabled ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen, - ctx->point_format, buf, blen, - f_rng, p_rng, - restart_enabled ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx, - const unsigned char **buf, - const unsigned char *end ) -{ - return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, - end - *buf ) ); -} - -/* - * Read the ServerKeyExhange parameters (RFC 4492) - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ -int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, - const unsigned char **buf, - const unsigned char *end ) -{ - int ret; - mbedtls_ecp_group_id grp_id; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - ECDH_VALIDATE_RET( *buf != NULL ); - ECDH_VALIDATE_RET( end != NULL ); - - if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) ) - != 0 ) - return( ret ); - - if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_read_params_internal( ctx, buf, end ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh, - buf, end ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side ) -{ - int ret; - - /* If it's not our key, just import the public part as Qp */ - if( side == MBEDTLS_ECDH_THEIRS ) - return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) ); - - /* Our key: import public (as Q) and private parts */ - if( side != MBEDTLS_ECDH_OURS ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 || - ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Get parameters from a keypair - */ -int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side ) -{ - int ret; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( key != NULL ); - ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS || - side == MBEDTLS_ECDH_THEIRS ); - - if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE ) - { - /* This is the first call to get_params(). Set up the context - * for use with the group. */ - if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 ) - return( ret ); - } - else - { - /* This is not the first call to get_params(). Check that the - * current key's group is the same as the context's, which was set - * from the first key's group. */ - if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_get_params_internal( ctx, key, side ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh, - key, side ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx, - size_t *olen, int point_format, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled ) -{ - int ret; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if( ctx->grp.pbits == 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( restart_enabled ) - rs_ctx = &ctx->rs; -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng, rs_ctx ) ) != 0 ) - return( ret ); -#else - if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng ) ) != 0 ) - return( ret ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen, - buf, blen ); -} - -/* - * Setup and export the client public value - */ -int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int restart_enabled = 0; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( olen != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - ECDH_VALIDATE_RET( f_rng != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen, - f_rng, p_rng, restart_enabled ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen, - ctx->point_format, buf, blen, - f_rng, p_rng, - restart_enabled ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx, - const unsigned char *buf, size_t blen ) -{ - int ret; - const unsigned char *p = buf; - - if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, - blen ) ) != 0 ) - return( ret ); - - if( (size_t)( p - buf ) != blen ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - return( 0 ); -} - -/* - * Parse and import the client's public value - */ -int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, - const unsigned char *buf, size_t blen ) -{ - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_read_public_internal( ctx, buf, blen ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh, - buf, blen ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx, - size_t *olen, unsigned char *buf, - size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled ) -{ - int ret; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if( ctx == NULL || ctx->grp.pbits == 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( restart_enabled ) - rs_ctx = &ctx->rs; -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp, - &ctx->d, f_rng, p_rng, - rs_ctx ) ) != 0 ) - { - return( ret ); - } -#else - if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, - &ctx->d, f_rng, p_rng ) ) != 0 ) - { - return( ret ); - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - if( mbedtls_mpi_size( &ctx->z ) > blen ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); - - if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen ); - - return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); -} - -/* - * Derive and export the shared secret - */ -int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int restart_enabled = 0; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( olen != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng, - restart_enabled ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf, - blen, f_rng, p_rng, - restart_enabled ) ); - default: - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } -#endif -} - -#endif /* MBEDTLS_ECDH_C */ diff --git a/library/ecdsa.c b/library/ecdsa.c deleted file mode 100644 index 58e1a5fcee..0000000000 --- a/library/ecdsa.c +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Elliptic curve DSA - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * References: - * - * SEC1 http://www.secg.org/index.php?action=secg,docs_secg - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECDSA_C) - -#include "mbedtls/ecdsa.h" -#include "mbedtls/asn1write.h" - -#include - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -#include "mbedtls/hmac_drbg.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/platform_util.h" - -/* Parameter validation macros based on platform_util.h */ -#define ECDSA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECDSA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/* - * Sub-context for ecdsa_verify() - */ -struct mbedtls_ecdsa_restart_ver -{ - mbedtls_mpi u1, u2; /* intermediate values */ - enum { /* what to do next? */ - ecdsa_ver_init = 0, /* getting started */ - ecdsa_ver_muladd, /* muladd step */ - } state; -}; - -/* - * Init verify restart sub-context - */ -static void ecdsa_restart_ver_init( mbedtls_ecdsa_restart_ver_ctx *ctx ) -{ - mbedtls_mpi_init( &ctx->u1 ); - mbedtls_mpi_init( &ctx->u2 ); - ctx->state = ecdsa_ver_init; -} - -/* - * Free the components of a verify restart sub-context - */ -static void ecdsa_restart_ver_free( mbedtls_ecdsa_restart_ver_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->u1 ); - mbedtls_mpi_free( &ctx->u2 ); - - ecdsa_restart_ver_init( ctx ); -} - -/* - * Sub-context for ecdsa_sign() - */ -struct mbedtls_ecdsa_restart_sig -{ - int sign_tries; - int key_tries; - mbedtls_mpi k; /* per-signature random */ - mbedtls_mpi r; /* r value */ - enum { /* what to do next? */ - ecdsa_sig_init = 0, /* getting started */ - ecdsa_sig_mul, /* doing ecp_mul() */ - ecdsa_sig_modn, /* mod N computations */ - } state; -}; - -/* - * Init verify sign sub-context - */ -static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx ) -{ - ctx->sign_tries = 0; - ctx->key_tries = 0; - mbedtls_mpi_init( &ctx->k ); - mbedtls_mpi_init( &ctx->r ); - ctx->state = ecdsa_sig_init; -} - -/* - * Free the components of a sign restart sub-context - */ -static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->k ); - mbedtls_mpi_free( &ctx->r ); -} - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/* - * Sub-context for ecdsa_sign_det() - */ -struct mbedtls_ecdsa_restart_det -{ - mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */ - enum { /* what to do next? */ - ecdsa_det_init = 0, /* getting started */ - ecdsa_det_sign, /* make signature */ - } state; -}; - -/* - * Init verify sign_det sub-context - */ -static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx ) -{ - mbedtls_hmac_drbg_init( &ctx->rng_ctx ); - ctx->state = ecdsa_det_init; -} - -/* - * Free the components of a sign_det restart sub-context - */ -static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_hmac_drbg_free( &ctx->rng_ctx ); - - ecdsa_restart_det_init( ctx ); -} -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#define ECDSA_RS_ECP ( rs_ctx == NULL ? NULL : &rs_ctx->ecp ) - -/* Utility macro for checking and updating ops budget */ -#define ECDSA_BUDGET( ops ) \ - MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, ECDSA_RS_ECP, ops ) ); - -/* Call this when entering a function that needs its own sub-context */ -#define ECDSA_RS_ENTER( SUB ) do { \ - /* reset ops count for this call if top-level */ \ - if( rs_ctx != NULL && rs_ctx->ecp.depth++ == 0 ) \ - rs_ctx->ecp.ops_done = 0; \ - \ - /* set up our own sub-context if needed */ \ - if( mbedtls_ecp_restart_is_enabled() && \ - rs_ctx != NULL && rs_ctx->SUB == NULL ) \ - { \ - rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \ - if( rs_ctx->SUB == NULL ) \ - return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \ - \ - ecdsa_restart_## SUB ##_init( rs_ctx->SUB ); \ - } \ -} while( 0 ) - -/* Call this when leaving a function that needs its own sub-context */ -#define ECDSA_RS_LEAVE( SUB ) do { \ - /* clear our sub-context when not in progress (done or error) */ \ - if( rs_ctx != NULL && rs_ctx->SUB != NULL && \ - ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \ - { \ - ecdsa_restart_## SUB ##_free( rs_ctx->SUB ); \ - mbedtls_free( rs_ctx->SUB ); \ - rs_ctx->SUB = NULL; \ - } \ - \ - if( rs_ctx != NULL ) \ - rs_ctx->ecp.depth--; \ -} while( 0 ) - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define ECDSA_RS_ECP NULL - -#define ECDSA_BUDGET( ops ) /* no-op; for compatibility */ - -#define ECDSA_RS_ENTER( SUB ) (void) rs_ctx -#define ECDSA_RS_LEAVE( SUB ) (void) rs_ctx - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/* - * Derive a suitable integer for group grp from a buffer of length len - * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 - */ -static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x, - const unsigned char *buf, size_t blen ) -{ - int ret; - size_t n_size = ( grp->nbits + 7 ) / 8; - size_t use_size = blen > n_size ? n_size : blen; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) ); - if( use_size * 8 > grp->nbits ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) ); - - /* While at it, reduce modulo N */ - if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) ); - -cleanup: - return( ret ); -} - -#if !defined(MBEDTLS_ECDSA_SIGN_ALT) -/* - * Compute ECDSA signature of a hashed message (SEC1 4.1.3) - * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) - */ -static int ecdsa_sign_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret, key_tries, sign_tries; - int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries; - mbedtls_ecp_point R; - mbedtls_mpi k, e, t; - mbedtls_mpi *pk = &k, *pr = r; - - /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ - if( grp->N.p == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* Make sure d is in range 1..n-1 */ - if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - mbedtls_ecp_point_init( &R ); - mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t ); - - ECDSA_RS_ENTER( sig ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - { - /* redirect to our context */ - p_sign_tries = &rs_ctx->sig->sign_tries; - p_key_tries = &rs_ctx->sig->key_tries; - pk = &rs_ctx->sig->k; - pr = &rs_ctx->sig->r; - - /* jump to current step */ - if( rs_ctx->sig->state == ecdsa_sig_mul ) - goto mul; - if( rs_ctx->sig->state == ecdsa_sig_modn ) - goto modn; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - *p_sign_tries = 0; - do - { - if( *p_sign_tries++ > 10 ) - { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - /* - * Steps 1-3: generate a suitable ephemeral keypair - * and set r = xR mod n - */ - *p_key_tries = 0; - do - { - if( *p_key_tries++ > 10 ) - { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, pk, f_rng, p_rng ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - rs_ctx->sig->state = ecdsa_sig_mul; - -mul: -#endif - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G, - f_rng, p_rng, ECDSA_RS_ECP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) ); - } - while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - rs_ctx->sig->state = ecdsa_sig_modn; - -modn: -#endif - /* - * Accounting for everything up to the end of the loop - * (step 6, but checking now avoids saving e and t) - */ - ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 ); - - /* - * Step 5: derive MPI from hashed message - */ - MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); - - /* - * Generate a random value to blind inv_mod in next step, - * avoiding a potential timing leak. - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng, p_rng ) ); - - /* - * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) ); - } - while( mbedtls_mpi_cmp_int( s, 0 ) == 0 ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - mbedtls_mpi_copy( r, pr ); -#endif - -cleanup: - mbedtls_ecp_point_free( &R ); - mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t ); - - ECDSA_RS_LEAVE( sig ); - - return( ret ); -} - -/* - * Compute ECDSA signature of a hashed message - */ -int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - ECDSA_VALIDATE_RET( grp != NULL ); - ECDSA_VALIDATE_RET( r != NULL ); - ECDSA_VALIDATE_RET( s != NULL ); - ECDSA_VALIDATE_RET( d != NULL ); - ECDSA_VALIDATE_RET( f_rng != NULL ); - ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); - - return( ecdsa_sign_restartable( grp, r, s, d, buf, blen, - f_rng, p_rng, NULL ) ); -} -#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/* - * Deterministic signature wrapper - */ -static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_hmac_drbg_context rng_ctx; - mbedtls_hmac_drbg_context *p_rng = &rng_ctx; - unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; - size_t grp_len = ( grp->nbits + 7 ) / 8; - const mbedtls_md_info_t *md_info; - mbedtls_mpi h; - - if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &h ); - mbedtls_hmac_drbg_init( &rng_ctx ); - - ECDSA_RS_ENTER( det ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->det != NULL ) - { - /* redirect to our context */ - p_rng = &rs_ctx->det->rng_ctx; - - /* jump to current step */ - if( rs_ctx->det->state == ecdsa_det_sign ) - goto sign; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); - MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); - mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->det != NULL ) - rs_ctx->det->state = ecdsa_det_sign; - -sign: -#endif -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng ); -#else - ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng, rs_ctx ); -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ - -cleanup: - mbedtls_hmac_drbg_free( &rng_ctx ); - mbedtls_mpi_free( &h ); - - ECDSA_RS_LEAVE( det ); - - return( ret ); -} - -/* - * Deterministic signature wrapper - */ -int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg ) -{ - ECDSA_VALIDATE_RET( grp != NULL ); - ECDSA_VALIDATE_RET( r != NULL ); - ECDSA_VALIDATE_RET( s != NULL ); - ECDSA_VALIDATE_RET( d != NULL ); - ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); - - return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) ); -} -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) -/* - * Verify ECDSA signature of hashed message (SEC1 4.1.4) - * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) - */ -static int ecdsa_verify_restartable( mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, const mbedtls_mpi *s, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_mpi e, s_inv, u1, u2; - mbedtls_ecp_point R; - mbedtls_mpi *pu1 = &u1, *pu2 = &u2; - - mbedtls_ecp_point_init( &R ); - mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); - mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 ); - - /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ - if( grp->N.p == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - ECDSA_RS_ENTER( ver ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ver != NULL ) - { - /* redirect to our context */ - pu1 = &rs_ctx->ver->u1; - pu2 = &rs_ctx->ver->u2; - - /* jump to current step */ - if( rs_ctx->ver->state == ecdsa_ver_muladd ) - goto muladd; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - /* - * Step 1: make sure r and s are in range 1..n-1 - */ - if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 || - mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - - /* - * Step 3: derive MPI from hashed message - */ - MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); - - /* - * Step 4: u1 = e / s mod n, u2 = r / s mod n - */ - ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ver != NULL ) - rs_ctx->ver->state = ecdsa_ver_muladd; - -muladd: -#endif - /* - * Step 5: R = u1 G + u2 Q - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp, - &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) ); - - if( mbedtls_ecp_is_zero( &R ) ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - - /* - * Step 6: convert xR to an integer (no-op) - * Step 7: reduce xR mod n (gives v) - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) ); - - /* - * Step 8: check if v (that is, R.X) is equal to r - */ - if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free( &R ); - mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); - mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 ); - - ECDSA_RS_LEAVE( ver ); - - return( ret ); -} - -/* - * Verify ECDSA signature of hashed message - */ -int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, - const mbedtls_mpi *s) -{ - ECDSA_VALIDATE_RET( grp != NULL ); - ECDSA_VALIDATE_RET( Q != NULL ); - ECDSA_VALIDATE_RET( r != NULL ); - ECDSA_VALIDATE_RET( s != NULL ); - ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); - - return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) ); -} -#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ - -/* - * Convert a signature (given by context) to ASN.1 - */ -static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, - unsigned char *sig, size_t *slen ) -{ - int ret; - unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; - unsigned char *p = buf + sizeof( buf ); - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - memcpy( sig, p, len ); - *slen = len; - - return( 0 ); -} - -/* - * Compute and write signature - */ -int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_mpi r, s; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - ECDSA_VALIDATE_RET( slen != NULL ); - - mbedtls_mpi_init( &r ); - mbedtls_mpi_init( &s ); - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - (void) f_rng; - (void) p_rng; - - MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d, - hash, hlen, md_alg, rs_ctx ) ); -#else - (void) md_alg; - -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d, - hash, hlen, f_rng, p_rng ) ); -#else - MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d, - hash, hlen, f_rng, p_rng, rs_ctx ) ); -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - - MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) ); - -cleanup: - mbedtls_mpi_free( &r ); - mbedtls_mpi_free( &s ); - - return( ret ); -} - -/* - * Compute and write signature - */ -int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - ECDSA_VALIDATE_RET( slen != NULL ); - return( mbedtls_ecdsa_write_signature_restartable( - ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) && \ - defined(MBEDTLS_ECDSA_DETERMINISTIC) -int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - mbedtls_md_type_t md_alg ) -{ - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - ECDSA_VALIDATE_RET( slen != NULL ); - return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen, - NULL, NULL ) ); -} -#endif - -/* - * Read and check signature - */ -int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen ) -{ - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - return( mbedtls_ecdsa_read_signature_restartable( - ctx, hash, hlen, sig, slen, NULL ) ); -} - -/* - * Restartable read and check signature - */ -int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char *p = (unsigned char *) sig; - const unsigned char *end = sig + slen; - size_t len; - mbedtls_mpi r, s; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - - mbedtls_mpi_init( &r ); - mbedtls_mpi_init( &s ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - if( p + len != end ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - goto cleanup; - } - - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 ) - { - ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } -#if defined(MBEDTLS_ECDSA_VERIFY_ALT) - if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen, - &ctx->Q, &r, &s ) ) != 0 ) - goto cleanup; -#else - if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen, - &ctx->Q, &r, &s, rs_ctx ) ) != 0 ) - goto cleanup; -#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ - - /* At this point we know that the buffer starts with a valid signature. - * Return 0 if the buffer just contains the signature, and a specific - * error code if the valid signature is followed by more data. */ - if( p != end ) - ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; - -cleanup: - mbedtls_mpi_free( &r ); - mbedtls_mpi_free( &s ); - - return( ret ); -} - -#if !defined(MBEDTLS_ECDSA_GENKEY_ALT) -/* - * Generate key pair - */ -int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret = 0; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( f_rng != NULL ); - - ret = mbedtls_ecp_group_load( &ctx->grp, gid ); - if( ret != 0 ) - return( ret ); - - return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, - &ctx->Q, f_rng, p_rng ) ); -} -#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */ - -/* - * Set context from an mbedtls_ecp_keypair - */ -int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ) -{ - int ret; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( key != NULL ); - - if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || - ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 || - ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) - { - mbedtls_ecdsa_free( ctx ); - } - - return( ret ); -} - -/* - * Initialize context - */ -void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ) -{ - ECDSA_VALIDATE( ctx != NULL ); - - mbedtls_ecp_keypair_init( ctx ); -} - -/* - * Free context - */ -void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_ecp_keypair_free( ctx ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ) -{ - ECDSA_VALIDATE( ctx != NULL ); - - mbedtls_ecp_restart_init( &ctx->ecp ); - - ctx->ver = NULL; - ctx->sig = NULL; -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - ctx->det = NULL; -#endif -} - -/* - * Free the components of a restart context - */ -void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_ecp_restart_free( &ctx->ecp ); - - ecdsa_restart_ver_free( ctx->ver ); - mbedtls_free( ctx->ver ); - ctx->ver = NULL; - - ecdsa_restart_sig_free( ctx->sig ); - mbedtls_free( ctx->sig ); - ctx->sig = NULL; - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - ecdsa_restart_det_free( ctx->det ); - mbedtls_free( ctx->det ); - ctx->det = NULL; -#endif -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#endif /* MBEDTLS_ECDSA_C */ diff --git a/library/ecjpake.c b/library/ecjpake.c deleted file mode 100644 index b276514e8b..0000000000 --- a/library/ecjpake.c +++ /dev/null @@ -1,1140 +0,0 @@ -/* - * Elliptic curve J-PAKE - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * References in the code are to the Thread v1.0 Specification, - * available to members of the Thread Group http://threadgroup.org/ - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECJPAKE_C) - -#include "mbedtls/ecjpake.h" -#include "mbedtls/platform_util.h" - -#include - -#if !defined(MBEDTLS_ECJPAKE_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define ECJPAKE_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECJPAKE_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * Convert a mbedtls_ecjpake_role to identifier string - */ -static const char * const ecjpake_id[] = { - "client", - "server" -}; - -#define ID_MINE ( ecjpake_id[ ctx->role ] ) -#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] ) - -/* - * Initialize context - */ -void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ) -{ - ECJPAKE_VALIDATE( ctx != NULL ); - - ctx->md_info = NULL; - mbedtls_ecp_group_init( &ctx->grp ); - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - - mbedtls_ecp_point_init( &ctx->Xm1 ); - mbedtls_ecp_point_init( &ctx->Xm2 ); - mbedtls_ecp_point_init( &ctx->Xp1 ); - mbedtls_ecp_point_init( &ctx->Xp2 ); - mbedtls_ecp_point_init( &ctx->Xp ); - - mbedtls_mpi_init( &ctx->xm1 ); - mbedtls_mpi_init( &ctx->xm2 ); - mbedtls_mpi_init( &ctx->s ); -} - -/* - * Free context - */ -void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ) -{ - if( ctx == NULL ) - return; - - ctx->md_info = NULL; - mbedtls_ecp_group_free( &ctx->grp ); - - mbedtls_ecp_point_free( &ctx->Xm1 ); - mbedtls_ecp_point_free( &ctx->Xm2 ); - mbedtls_ecp_point_free( &ctx->Xp1 ); - mbedtls_ecp_point_free( &ctx->Xp2 ); - mbedtls_ecp_point_free( &ctx->Xp ); - - mbedtls_mpi_free( &ctx->xm1 ); - mbedtls_mpi_free( &ctx->xm2 ); - mbedtls_mpi_free( &ctx->s ); -} - -/* - * Setup context - */ -int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, - mbedtls_ecjpake_role role, - mbedtls_md_type_t hash, - mbedtls_ecp_group_id curve, - const unsigned char *secret, - size_t len ) -{ - int ret; - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT || - role == MBEDTLS_ECJPAKE_SERVER ); - ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 ); - - ctx->role = role; - - if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL ) - return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) ); - -cleanup: - if( ret != 0 ) - mbedtls_ecjpake_free( ctx ); - - return( ret ); -} - -/* - * Check if context is ready for use - */ -int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ) -{ - ECJPAKE_VALIDATE_RET( ctx != NULL ); - - if( ctx->md_info == NULL || - ctx->grp.id == MBEDTLS_ECP_DP_NONE || - ctx->s.p == NULL ) - { - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - return( 0 ); -} - -/* - * Write a point plus its length to a buffer - */ -static int ecjpake_write_len_point( unsigned char **p, - const unsigned char *end, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *P ) -{ - int ret; - size_t len; - - /* Need at least 4 for length plus 1 for point */ - if( end < *p || end - *p < 5 ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - ret = mbedtls_ecp_point_write_binary( grp, P, pf, - &len, *p + 4, end - ( *p + 4 ) ); - if( ret != 0 ) - return( ret ); - - (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF ); - (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF ); - (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF ); - (*p)[3] = (unsigned char)( ( len ) & 0xFF ); - - *p += 4 + len; - - return( 0 ); -} - -/* - * Size of the temporary buffer for ecjpake_hash: - * 3 EC points plus their length, plus ID and its length (4 + 6 bytes) - */ -#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 ) - -/* - * Compute hash for ZKP (7.4.2.2.2.1) - */ -static int ecjpake_hash( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_ecp_point *V, - const mbedtls_ecp_point *X, - const char *id, - mbedtls_mpi *h ) -{ - int ret; - unsigned char buf[ECJPAKE_HASH_BUF_LEN]; - unsigned char *p = buf; - const unsigned char *end = buf + sizeof( buf ); - const size_t id_len = strlen( id ); - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - - /* Write things to temporary buffer */ - MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) ); - MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) ); - MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) ); - - if( end - p < 4 ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF ); - *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF ); - *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( id_len ) & 0xFF ); - - if( end < p || (size_t)( end - p ) < id_len ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - memcpy( p, id, id_len ); - p += id_len; - - /* Compute hash */ - mbedtls_md( md_info, buf, p - buf, hash ); - - /* Turn it into an integer mod n */ - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash, - mbedtls_md_get_size( md_info ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) ); - -cleanup: - return( ret ); -} - -/* - * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) - */ -static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_ecp_point *X, - const char *id, - const unsigned char **p, - const unsigned char *end ) -{ - int ret; - mbedtls_ecp_point V, VV; - mbedtls_mpi r, h; - size_t r_len; - - mbedtls_ecp_point_init( &V ); - mbedtls_ecp_point_init( &VV ); - mbedtls_mpi_init( &r ); - mbedtls_mpi_init( &h ); - - /* - * struct { - * ECPoint V; - * opaque r<1..2^8-1>; - * } ECSchnorrZKP; - */ - if( end < *p ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) ); - - if( end < *p || (size_t)( end - *p ) < 1 ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - r_len = *(*p)++; - - if( end < *p || (size_t)( end - *p ) < r_len ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) ); - *p += r_len; - - /* - * Verification - */ - MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp, - &VV, &h, X, &r, G ) ); - - if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free( &V ); - mbedtls_ecp_point_free( &VV ); - mbedtls_mpi_free( &r ); - mbedtls_mpi_free( &h ); - - return( ret ); -} - -/* - * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) - */ -static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_mpi *x, - const mbedtls_ecp_point *X, - const char *id, - unsigned char **p, - const unsigned char *end, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_ecp_point V; - mbedtls_mpi v; - mbedtls_mpi h; /* later recycled to hold r */ - size_t len; - - if( end < *p ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - mbedtls_ecp_point_init( &V ); - mbedtls_mpi_init( &v ); - mbedtls_mpi_init( &h ); - - /* Compute signature */ - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, - G, &v, &V, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */ - - /* Write it out */ - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V, - pf, &len, *p, end - *p ) ); - *p += len; - - len = mbedtls_mpi_size( &h ); /* actually r */ - if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 ) - { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - - *(*p)++ = (unsigned char)( len & 0xFF ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */ - *p += len; - -cleanup: - mbedtls_ecp_point_free( &V ); - mbedtls_mpi_free( &v ); - mbedtls_mpi_free( &h ); - - return( ret ); -} - -/* - * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof - * Output: verified public key X - */ -static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_ecp_point *X, - const char *id, - const unsigned char **p, - const unsigned char *end ) -{ - int ret; - - if( end < *p ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * struct { - * ECPoint X; - * ECSchnorrZKP zkp; - * } ECJPAKEKeyKP; - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) ); - if( mbedtls_ecp_is_zero( X ) ) - { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - - MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) ); - -cleanup: - return( ret ); -} - -/* - * Generate an ECJPAKEKeyKP - * Output: the serialized structure, plus private/public key pair - */ -static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_mpi *x, - mbedtls_ecp_point *X, - const char *id, - unsigned char **p, - const unsigned char *end, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t len; - - if( end < *p ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - /* Generate key (7.4.2.3.1) and write it out */ - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X, - pf, &len, *p, end - *p ) ); - *p += len; - - /* Generate and write proof */ - MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id, - p, end, f_rng, p_rng ) ); - -cleanup: - return( ret ); -} - -/* - * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs - * Ouputs: verified peer public keys Xa, Xb - */ -static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_ecp_point *Xa, - mbedtls_ecp_point *Xb, - const char *id, - const unsigned char *buf, - size_t len ) -{ - int ret; - const unsigned char *p = buf; - const unsigned char *end = buf + len; - - /* - * struct { - * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; - * } ECJPAKEKeyKPPairList; - */ - MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) ); - MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) ); - - if( p != end ) - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - -cleanup: - return( ret ); -} - -/* - * Generate a ECJPAKEKeyKPPairList - * Outputs: the serialized structure, plus two private/public key pairs - */ -static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_mpi *xm1, - mbedtls_ecp_point *Xa, - mbedtls_mpi *xm2, - mbedtls_ecp_point *Xb, - const char *id, - unsigned char *buf, - size_t len, - size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char *p = buf; - const unsigned char *end = buf + len; - - MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id, - &p, end, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id, - &p, end, f_rng, p_rng ) ); - - *olen = p - buf; - -cleanup: - return( ret ); -} - -/* - * Read and process the first round message - */ -int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len ) -{ - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - - return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format, - &ctx->grp.G, - &ctx->Xp1, &ctx->Xp2, ID_PEER, - buf, len ) ); -} - -/* - * Generate and write the first round message - */ -int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - ECJPAKE_VALIDATE_RET( olen != NULL ); - ECJPAKE_VALIDATE_RET( f_rng != NULL ); - - return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format, - &ctx->grp.G, - &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, - ID_MINE, buf, len, olen, f_rng, p_rng ) ); -} - -/* - * Compute the sum of three points R = A + B + C - */ -static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *A, - const mbedtls_ecp_point *B, - const mbedtls_ecp_point *C ) -{ - int ret; - mbedtls_mpi one; - - mbedtls_mpi_init( &one ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) ); - -cleanup: - mbedtls_mpi_free( &one ); - - return( ret ); -} - -/* - * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) - */ -int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len ) -{ - int ret; - const unsigned char *p = buf; - const unsigned char *end = buf + len; - mbedtls_ecp_group grp; - mbedtls_ecp_point G; /* C: GB, S: GA */ - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - - mbedtls_ecp_group_init( &grp ); - mbedtls_ecp_point_init( &G ); - - /* - * Server: GA = X3 + X4 + X1 (7.4.2.6.1) - * Client: GB = X1 + X2 + X3 (7.4.2.5.1) - * Unified: G = Xm1 + Xm2 + Xp1 - * We need that before parsing in order to check Xp as we read it - */ - MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, - &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) ); - - /* - * struct { - * ECParameters curve_params; // only client reading server msg - * ECJPAKEKeyKP ecjpake_key_kp; - * } Client/ServerECJPAKEParams; - */ - if( ctx->role == MBEDTLS_ECJPAKE_CLIENT ) - { - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) ); - if( grp.id != ctx->grp.id ) - { - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - goto cleanup; - } - } - - MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp, - ctx->point_format, - &G, &ctx->Xp, ID_PEER, &p, end ) ); - - if( p != end ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - -cleanup: - mbedtls_ecp_group_free( &grp ); - mbedtls_ecp_point_free( &G ); - - return( ret ); -} - -/* - * Compute R = +/- X * S mod N, taking care not to leak S - */ -static int ecjpake_mul_secret( mbedtls_mpi *R, int sign, - const mbedtls_mpi *X, - const mbedtls_mpi *S, - const mbedtls_mpi *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_mpi b; /* Blinding value, then s + N * blinding */ - - mbedtls_mpi_init( &b ); - - /* b = s + rnd-128-bit * N */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) ); - - /* R = sign * X * b mod N */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) ); - R->s *= sign; - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) ); - -cleanup: - mbedtls_mpi_free( &b ); - - return( ret ); -} - -/* - * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) - */ -int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_ecp_point G; /* C: GA, S: GB */ - mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ - mbedtls_mpi xm; /* C: xc, S: xs */ - unsigned char *p = buf; - const unsigned char *end = buf + len; - size_t ec_len; - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - ECJPAKE_VALIDATE_RET( olen != NULL ); - ECJPAKE_VALIDATE_RET( f_rng != NULL ); - - mbedtls_ecp_point_init( &G ); - mbedtls_ecp_point_init( &Xm ); - mbedtls_mpi_init( &xm ); - - /* - * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) - * - * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA - * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB - * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G - */ - MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, - &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) ); - MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s, - &ctx->grp.N, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) ); - - /* - * Now write things out - * - * struct { - * ECParameters curve_params; // only server writing its message - * ECJPAKEKeyKP ecjpake_key_kp; - * } Client/ServerECJPAKEParams; - */ - if( ctx->role == MBEDTLS_ECJPAKE_SERVER ) - { - if( end < p ) - { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len, - p, end - p ) ); - p += ec_len; - } - - if( end < p ) - { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm, - ctx->point_format, &ec_len, p, end - p ) ); - p += ec_len; - - MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp, - ctx->point_format, - &G, &xm, &Xm, ID_MINE, - &p, end, f_rng, p_rng ) ); - - *olen = p - buf; - -cleanup: - mbedtls_ecp_point_free( &G ); - mbedtls_ecp_point_free( &Xm ); - mbedtls_mpi_free( &xm ); - - return( ret ); -} - -/* - * Derive PMS (7.4.2.7 / 7.4.2.8) - */ -int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_ecp_point K; - mbedtls_mpi m_xm2_s, one; - unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; - size_t x_bytes; - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - ECJPAKE_VALIDATE_RET( olen != NULL ); - ECJPAKE_VALIDATE_RET( f_rng != NULL ); - - *olen = mbedtls_md_get_size( ctx->md_info ); - if( len < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - mbedtls_ecp_point_init( &K ); - mbedtls_mpi_init( &m_xm2_s ); - mbedtls_mpi_init( &one ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); - - /* - * Client: K = ( Xs - X4 * x2 * s ) * x2 - * Server: K = ( Xc - X2 * x4 * s ) * x4 - * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 - */ - MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s, - &ctx->grp.N, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K, - &one, &ctx->Xp, - &m_xm2_s, &ctx->Xp2 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K, - f_rng, p_rng ) ); - - /* PMS = SHA-256( K.X ) */ - x_bytes = ( ctx->grp.pbits + 7 ) / 8; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) ); - MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) ); - -cleanup: - mbedtls_ecp_point_free( &K ); - mbedtls_mpi_free( &m_xm2_s ); - mbedtls_mpi_free( &one ); - - return( ret ); -} - -#undef ID_MINE -#undef ID_PEER - -#endif /* ! MBEDTLS_ECJPAKE_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif - -#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - !defined(MBEDTLS_SHA256_C) -int mbedtls_ecjpake_self_test( int verbose ) -{ - (void) verbose; - return( 0 ); -} -#else - -static const unsigned char ecjpake_test_password[] = { - 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, - 0x65, 0x73, 0x74 -}; - -static const unsigned char ecjpake_test_x1[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 -}; - -static const unsigned char ecjpake_test_x2[] = { - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 -}; - -static const unsigned char ecjpake_test_x3[] = { - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 -}; - -static const unsigned char ecjpake_test_x4[] = { - 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, - 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 -}; - -static const unsigned char ecjpake_test_cli_one[] = { - 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, - 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, - 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, - 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, - 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, - 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, - 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, - 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, - 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, - 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, - 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, - 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, - 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, - 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, - 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, - 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, - 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, - 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, - 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, - 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, - 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, - 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, - 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, - 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, - 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, - 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, - 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, - 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 -}; - -static const unsigned char ecjpake_test_srv_one[] = { - 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, - 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, - 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, - 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, - 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, - 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, - 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, - 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, - 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, - 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, - 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, - 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, - 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, - 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, - 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, - 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, - 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, - 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, - 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, - 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, - 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, - 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, - 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, - 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, - 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, - 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, - 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, - 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 -}; - -static const unsigned char ecjpake_test_srv_two[] = { - 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, - 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, - 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, - 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, - 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, - 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, - 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, - 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, - 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, - 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, - 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, - 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, - 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, - 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c -}; - -static const unsigned char ecjpake_test_cli_two[] = { - 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, - 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, - 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, - 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, - 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, - 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, - 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, - 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, - 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, - 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, - 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, - 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, - 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, - 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c -}; - -static const unsigned char ecjpake_test_pms[] = { - 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, - 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, - 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 -}; - -/* Load my private keys and generate the corresponding public keys */ -static int ecjpake_test_load( mbedtls_ecjpake_context *ctx, - const unsigned char *xm1, size_t len1, - const unsigned char *xm2, size_t len2 ) -{ - int ret; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1, - &ctx->grp.G, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2, - &ctx->grp.G, NULL, NULL ) ); - -cleanup: - return( ret ); -} - -/* For tests we don't need a secure RNG; - * use the LGC from Numerical Recipes for simplicity */ -static int ecjpake_lgc( void *p, unsigned char *out, size_t len ) -{ - static uint32_t x = 42; - (void) p; - - while( len > 0 ) - { - size_t use_len = len > 4 ? 4 : len; - x = 1664525 * x + 1013904223; - memcpy( out, &x, use_len ); - out += use_len; - len -= use_len; - } - - return( 0 ); -} - -#define TEST_ASSERT( x ) \ - do { \ - if( x ) \ - ret = 0; \ - else \ - { \ - ret = 1; \ - goto cleanup; \ - } \ - } while( 0 ) - -/* - * Checkup routine - */ -int mbedtls_ecjpake_self_test( int verbose ) -{ - int ret; - mbedtls_ecjpake_context cli; - mbedtls_ecjpake_context srv; - unsigned char buf[512], pms[32]; - size_t len, pmslen; - - mbedtls_ecjpake_init( &cli ); - mbedtls_ecjpake_init( &srv ); - - if( verbose != 0 ) - mbedtls_printf( " ECJPAKE test #0 (setup): " ); - - TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT, - MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, - ecjpake_test_password, - sizeof( ecjpake_test_password ) ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER, - MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, - ecjpake_test_password, - sizeof( ecjpake_test_password ) ) == 0 ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " ECJPAKE test #1 (random handshake): " ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, - pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( len == pmslen ); - TEST_ASSERT( memcmp( buf, pms, len ) == 0 ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " ECJPAKE test #2 (reference handshake): " ); - - /* Simulate generation of round one */ - MBEDTLS_MPI_CHK( ecjpake_test_load( &cli, - ecjpake_test_x1, sizeof( ecjpake_test_x1 ), - ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) ); - - MBEDTLS_MPI_CHK( ecjpake_test_load( &srv, - ecjpake_test_x3, sizeof( ecjpake_test_x3 ), - ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) ); - - /* Read round one */ - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, - ecjpake_test_cli_one, - sizeof( ecjpake_test_cli_one ) ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, - ecjpake_test_srv_one, - sizeof( ecjpake_test_srv_one ) ) == 0 ); - - /* Skip generation of round two, read round two */ - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, - ecjpake_test_srv_two, - sizeof( ecjpake_test_srv_two ) ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, - ecjpake_test_cli_two, - sizeof( ecjpake_test_cli_two ) ) == 0 ); - - /* Server derives PMS */ - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); - TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); - - memset( buf, 0, len ); /* Avoid interferences with next step */ - - /* Client derives PMS */ - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); - TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -cleanup: - mbedtls_ecjpake_free( &cli ); - mbedtls_ecjpake_free( &srv ); - - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#undef TEST_ASSERT - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */ - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ECJPAKE_C */ diff --git a/library/ecp.c b/library/ecp.c deleted file mode 100644 index 7a263b234a..0000000000 --- a/library/ecp.c +++ /dev/null @@ -1,3089 +0,0 @@ -/* - * Elliptic curves over GF(p): generic functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * References: - * - * SEC1 http://www.secg.org/index.php?action=secg,docs_secg - * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone - * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf - * RFC 4492 for the related TLS structures and constants - * RFC 7748 for the Curve448 and Curve25519 curve definitions - * - * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf - * - * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis - * for elliptic curve cryptosystems. In : Cryptographic Hardware and - * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. - * - * - * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to - * render ECC resistant against Side Channel Attacks. IACR Cryptology - * ePrint Archive, 2004, vol. 2004, p. 342. - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -/** - * \brief Function level alternative implementation. - * - * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to - * replace certain functions in this module. The alternative implementations are - * typically hardware accelerators and need to activate the hardware before the - * computation starts and deactivate it after it finishes. The - * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve - * this purpose. - * - * To preserve the correct functionality the following conditions must hold: - * - * - The alternative implementation must be activated by - * mbedtls_internal_ecp_init() before any of the replaceable functions is - * called. - * - mbedtls_internal_ecp_free() must \b only be called when the alternative - * implementation is activated. - * - mbedtls_internal_ecp_init() must \b not be called when the alternative - * implementation is activated. - * - Public functions must not return while the alternative implementation is - * activated. - * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and - * before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) ) - * \endcode ensures that the alternative implementation supports the current - * group. - */ -#if defined(MBEDTLS_ECP_INTERNAL_ALT) -#endif - -#if defined(MBEDTLS_ECP_C) - -#include "mbedtls/ecp.h" -#include "mbedtls/threading.h" -#include "mbedtls/platform_util.h" - -#include - -#if !defined(MBEDTLS_ECP_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define ECP_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECP_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ecp_internal.h" - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * Counts of point addition and doubling, and field multiplications. - * Used to test resistance of point multiplication to simple timing attacks. - */ -static unsigned long add_count, dbl_count, mul_count; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Maximum number of "basic operations" to be done in a row. - * - * Default value 0 means that ECC operations will not yield. - * Note that regardless of the value of ecp_max_ops, always at - * least one step is performed before yielding. - * - * Setting ecp_max_ops=1 can be suitable for testing purposes - * as it will interrupt computation at all possible points. - */ -static unsigned ecp_max_ops = 0; - -/* - * Set ecp_max_ops - */ -void mbedtls_ecp_set_max_ops( unsigned max_ops ) -{ - ecp_max_ops = max_ops; -} - -/* - * Check if restart is enabled - */ -int mbedtls_ecp_restart_is_enabled( void ) -{ - return( ecp_max_ops != 0 ); -} - -/* - * Restart sub-context for ecp_mul_comb() - */ -struct mbedtls_ecp_restart_mul -{ - mbedtls_ecp_point R; /* current intermediate result */ - size_t i; /* current index in various loops, 0 outside */ - mbedtls_ecp_point *T; /* table for precomputed points */ - unsigned char T_size; /* number of points in table T */ - enum { /* what were we doing last time we returned? */ - ecp_rsm_init = 0, /* nothing so far, dummy initial state */ - ecp_rsm_pre_dbl, /* precompute 2^n multiples */ - ecp_rsm_pre_norm_dbl, /* normalize precomputed 2^n multiples */ - ecp_rsm_pre_add, /* precompute remaining points by adding */ - ecp_rsm_pre_norm_add, /* normalize all precomputed points */ - ecp_rsm_comb_core, /* ecp_mul_comb_core() */ - ecp_rsm_final_norm, /* do the final normalization */ - } state; -}; - -/* - * Init restart_mul sub-context - */ -static void ecp_restart_rsm_init( mbedtls_ecp_restart_mul_ctx *ctx ) -{ - mbedtls_ecp_point_init( &ctx->R ); - ctx->i = 0; - ctx->T = NULL; - ctx->T_size = 0; - ctx->state = ecp_rsm_init; -} - -/* - * Free the components of a restart_mul sub-context - */ -static void ecp_restart_rsm_free( mbedtls_ecp_restart_mul_ctx *ctx ) -{ - unsigned char i; - - if( ctx == NULL ) - return; - - mbedtls_ecp_point_free( &ctx->R ); - - if( ctx->T != NULL ) - { - for( i = 0; i < ctx->T_size; i++ ) - mbedtls_ecp_point_free( ctx->T + i ); - mbedtls_free( ctx->T ); - } - - ecp_restart_rsm_init( ctx ); -} - -/* - * Restart context for ecp_muladd() - */ -struct mbedtls_ecp_restart_muladd -{ - mbedtls_ecp_point mP; /* mP value */ - mbedtls_ecp_point R; /* R intermediate result */ - enum { /* what should we do next? */ - ecp_rsma_mul1 = 0, /* first multiplication */ - ecp_rsma_mul2, /* second multiplication */ - ecp_rsma_add, /* addition */ - ecp_rsma_norm, /* normalization */ - } state; -}; - -/* - * Init restart_muladd sub-context - */ -static void ecp_restart_ma_init( mbedtls_ecp_restart_muladd_ctx *ctx ) -{ - mbedtls_ecp_point_init( &ctx->mP ); - mbedtls_ecp_point_init( &ctx->R ); - ctx->state = ecp_rsma_mul1; -} - -/* - * Free the components of a restart_muladd sub-context - */ -static void ecp_restart_ma_free( mbedtls_ecp_restart_muladd_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_ecp_point_free( &ctx->mP ); - mbedtls_ecp_point_free( &ctx->R ); - - ecp_restart_ma_init( ctx ); -} - -/* - * Initialize a restart context - */ -void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ) -{ - ECP_VALIDATE( ctx != NULL ); - ctx->ops_done = 0; - ctx->depth = 0; - ctx->rsm = NULL; - ctx->ma = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - ecp_restart_rsm_free( ctx->rsm ); - mbedtls_free( ctx->rsm ); - - ecp_restart_ma_free( ctx->ma ); - mbedtls_free( ctx->ma ); - - mbedtls_ecp_restart_init( ctx ); -} - -/* - * Check if we can do the next step - */ -int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, - mbedtls_ecp_restart_ctx *rs_ctx, - unsigned ops ) -{ - ECP_VALIDATE_RET( grp != NULL ); - - if( rs_ctx != NULL && ecp_max_ops != 0 ) - { - /* scale depending on curve size: the chosen reference is 256-bit, - * and multiplication is quadratic. Round to the closest integer. */ - if( grp->pbits >= 512 ) - ops *= 4; - else if( grp->pbits >= 384 ) - ops *= 2; - - /* Avoid infinite loops: always allow first step. - * Because of that, however, it's not generally true - * that ops_done <= ecp_max_ops, so the check - * ops_done > ecp_max_ops below is mandatory. */ - if( ( rs_ctx->ops_done != 0 ) && - ( rs_ctx->ops_done > ecp_max_ops || - ops > ecp_max_ops - rs_ctx->ops_done ) ) - { - return( MBEDTLS_ERR_ECP_IN_PROGRESS ); - } - - /* update running count */ - rs_ctx->ops_done += ops; - } - - return( 0 ); -} - -/* Call this when entering a function that needs its own sub-context */ -#define ECP_RS_ENTER( SUB ) do { \ - /* reset ops count for this call if top-level */ \ - if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) \ - rs_ctx->ops_done = 0; \ - \ - /* set up our own sub-context if needed */ \ - if( mbedtls_ecp_restart_is_enabled() && \ - rs_ctx != NULL && rs_ctx->SUB == NULL ) \ - { \ - rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \ - if( rs_ctx->SUB == NULL ) \ - return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \ - \ - ecp_restart_## SUB ##_init( rs_ctx->SUB ); \ - } \ -} while( 0 ) - -/* Call this when leaving a function that needs its own sub-context */ -#define ECP_RS_LEAVE( SUB ) do { \ - /* clear our sub-context when not in progress (done or error) */ \ - if( rs_ctx != NULL && rs_ctx->SUB != NULL && \ - ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \ - { \ - ecp_restart_## SUB ##_free( rs_ctx->SUB ); \ - mbedtls_free( rs_ctx->SUB ); \ - rs_ctx->SUB = NULL; \ - } \ - \ - if( rs_ctx != NULL ) \ - rs_ctx->depth--; \ -} while( 0 ) - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define ECP_RS_ENTER( sub ) (void) rs_ctx; -#define ECP_RS_LEAVE( sub ) (void) rs_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -#define ECP_SHORTWEIERSTRASS -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ - defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -#define ECP_MONTGOMERY -#endif - -/* - * List of supported curves: - * - internal ID - * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2) - * - size in bits - * - readable name - * - * Curves are listed in order: largest curves first, and for a given size, - * fastest curves first. This provides the default order for the SSL module. - * - * Reminder: update profiles in x509_crt.c when adding a new curves! - */ -static const mbedtls_ecp_curve_info ecp_supported_curves[] = -{ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, -#endif - { MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, -}; - -#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \ - sizeof( ecp_supported_curves[0] ) - -static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; - -/* - * List of supported curves and associated info - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ) -{ - return( ecp_supported_curves ); -} - -/* - * List of supported curves, group ID only - */ -const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ) -{ - static int init_done = 0; - - if( ! init_done ) - { - size_t i = 0; - const mbedtls_ecp_curve_info *curve_info; - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - ecp_supported_grp_id[i++] = curve_info->grp_id; - } - ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE; - - init_done = 1; - } - - return( ecp_supported_grp_id ); -} - -/* - * Get the curve info for the internal identifier - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ) -{ - const mbedtls_ecp_curve_info *curve_info; - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - if( curve_info->grp_id == grp_id ) - return( curve_info ); - } - - return( NULL ); -} - -/* - * Get the curve info from the TLS identifier - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ) -{ - const mbedtls_ecp_curve_info *curve_info; - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - if( curve_info->tls_id == tls_id ) - return( curve_info ); - } - - return( NULL ); -} - -/* - * Get the curve info from the name - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ) -{ - const mbedtls_ecp_curve_info *curve_info; - - if( name == NULL ) - return( NULL ); - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - if( strcmp( curve_info->name, name ) == 0 ) - return( curve_info ); - } - - return( NULL ); -} - -/* - * Get the type of a curve - */ -mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp ) -{ - if( grp->G.X.p == NULL ) - return( MBEDTLS_ECP_TYPE_NONE ); - - if( grp->G.Y.p == NULL ) - return( MBEDTLS_ECP_TYPE_MONTGOMERY ); - else - return( MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ); -} - -/* - * Initialize (the components of) a point - */ -void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) -{ - ECP_VALIDATE( pt != NULL ); - - mbedtls_mpi_init( &pt->X ); - mbedtls_mpi_init( &pt->Y ); - mbedtls_mpi_init( &pt->Z ); -} - -/* - * Initialize (the components of) a group - */ -void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) -{ - ECP_VALIDATE( grp != NULL ); - - grp->id = MBEDTLS_ECP_DP_NONE; - mbedtls_mpi_init( &grp->P ); - mbedtls_mpi_init( &grp->A ); - mbedtls_mpi_init( &grp->B ); - mbedtls_ecp_point_init( &grp->G ); - mbedtls_mpi_init( &grp->N ); - grp->pbits = 0; - grp->nbits = 0; - grp->h = 0; - grp->modp = NULL; - grp->t_pre = NULL; - grp->t_post = NULL; - grp->t_data = NULL; - grp->T = NULL; - grp->T_size = 0; -} - -/* - * Initialize (the components of) a key pair - */ -void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ) -{ - ECP_VALIDATE( key != NULL ); - - mbedtls_ecp_group_init( &key->grp ); - mbedtls_mpi_init( &key->d ); - mbedtls_ecp_point_init( &key->Q ); -} - -/* - * Unallocate (the components of) a point - */ -void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ) -{ - if( pt == NULL ) - return; - - mbedtls_mpi_free( &( pt->X ) ); - mbedtls_mpi_free( &( pt->Y ) ); - mbedtls_mpi_free( &( pt->Z ) ); -} - -/* - * Unallocate (the components of) a group - */ -void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ) -{ - size_t i; - - if( grp == NULL ) - return; - - if( grp->h != 1 ) - { - mbedtls_mpi_free( &grp->P ); - mbedtls_mpi_free( &grp->A ); - mbedtls_mpi_free( &grp->B ); - mbedtls_ecp_point_free( &grp->G ); - mbedtls_mpi_free( &grp->N ); - } - - if( grp->T != NULL ) - { - for( i = 0; i < grp->T_size; i++ ) - mbedtls_ecp_point_free( &grp->T[i] ); - mbedtls_free( grp->T ); - } - - mbedtls_platform_zeroize( grp, sizeof( mbedtls_ecp_group ) ); -} - -/* - * Unallocate (the components of) a key pair - */ -void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ) -{ - if( key == NULL ) - return; - - mbedtls_ecp_group_free( &key->grp ); - mbedtls_mpi_free( &key->d ); - mbedtls_ecp_point_free( &key->Q ); -} - -/* - * Copy the contents of a point - */ -int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) -{ - int ret; - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Z, &Q->Z ) ); - -cleanup: - return( ret ); -} - -/* - * Copy the contents of a group object - */ -int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ) -{ - ECP_VALIDATE_RET( dst != NULL ); - ECP_VALIDATE_RET( src != NULL ); - - return( mbedtls_ecp_group_load( dst, src->id ) ); -} - -/* - * Set point to zero - */ -int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ) -{ - int ret; - ECP_VALIDATE_RET( pt != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z , 0 ) ); - -cleanup: - return( ret ); -} - -/* - * Tell if a point is zero - */ -int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) -{ - ECP_VALIDATE_RET( pt != NULL ); - - return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); -} - -/* - * Compare two points lazily - */ -int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q ) -{ - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - - if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 && - mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 && - mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 ) - { - return( 0 ); - } - - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); -} - -/* - * Import a non-zero point from ASCII strings - */ -int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, - const char *x, const char *y ) -{ - int ret; - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( x != NULL ); - ECP_VALIDATE_RET( y != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); - -cleanup: - return( ret ); -} - -/* - * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748) - */ -int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *P, - int format, size_t *olen, - unsigned char *buf, size_t buflen ) -{ - int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - size_t plen; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || - format == MBEDTLS_ECP_PF_COMPRESSED ); - - plen = mbedtls_mpi_size( &grp->P ); - -#if defined(ECP_MONTGOMERY) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - { - *olen = plen; - if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) ); - } -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - { - /* - * Common case: P == 0 - */ - if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) - { - if( buflen < 1 ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - buf[0] = 0x00; - *olen = 1; - - return( 0 ); - } - - if( format == MBEDTLS_ECP_PF_UNCOMPRESSED ) - { - *olen = 2 * plen + 1; - - if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - buf[0] = 0x04; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); - } - else if( format == MBEDTLS_ECP_PF_COMPRESSED ) - { - *olen = plen + 1; - - if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); - } - } -#endif - -cleanup: - return( ret ); -} - -/* - * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748) - */ -int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char *buf, size_t ilen ) -{ - int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - size_t plen; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - - if( ilen < 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - plen = mbedtls_mpi_size( &grp->P ); - -#if defined(ECP_MONTGOMERY) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - { - if( plen != ilen ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &pt->X, buf, plen ) ); - mbedtls_mpi_free( &pt->Y ); - - if( grp->id == MBEDTLS_ECP_DP_CURVE25519 ) - /* Set most significant bit to 0 as prescribed in RFC7748 §5 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); - } -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - { - if( buf[0] == 0x00 ) - { - if( ilen == 1 ) - return( mbedtls_ecp_set_zero( pt ) ); - else - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - if( buf[0] != 0x04 ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - if( ilen != 2 * plen + 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, - buf + 1 + plen, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); - } -#endif - -cleanup: - return( ret ); -} - -/* - * Import a point from a TLS ECPoint record (RFC 4492) - * struct { - * opaque point <1..2^8-1>; - * } ECPoint; - */ -int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char **buf, size_t buf_len ) -{ - unsigned char data_len; - const unsigned char *buf_start; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); - - /* - * We must have at least two bytes (1 for length, at least one for data) - */ - if( buf_len < 2 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - data_len = *(*buf)++; - if( data_len < 1 || data_len > buf_len - 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * Save buffer start for read_binary and update buf - */ - buf_start = *buf; - *buf += data_len; - - return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) ); -} - -/* - * Export a point as a TLS ECPoint record (RFC 4492) - * struct { - * opaque point <1..2^8-1>; - * } ECPoint; - */ -int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, - int format, size_t *olen, - unsigned char *buf, size_t blen ) -{ - int ret; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || - format == MBEDTLS_ECP_PF_COMPRESSED ); - - /* - * buffer length must be at least one, for our length byte - */ - if( blen < 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_ecp_point_write_binary( grp, pt, format, - olen, buf + 1, blen - 1) ) != 0 ) - return( ret ); - - /* - * write length to the first byte and update total length - */ - buf[0] = (unsigned char) *olen; - ++*olen; - - return( 0 ); -} - -/* - * Set a group from an ECParameters record (RFC 4492) - */ -int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, - const unsigned char **buf, size_t len ) -{ - int ret; - mbedtls_ecp_group_id grp_id; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); - - if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 ) - return( ret ); - - return( mbedtls_ecp_group_load( grp, grp_id ) ); -} - -/* - * Read a group id from an ECParameters record (RFC 4492) and convert it to - * mbedtls_ecp_group_id. - */ -int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, - const unsigned char **buf, size_t len ) -{ - uint16_t tls_id; - const mbedtls_ecp_curve_info *curve_info; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); - - /* - * We expect at least three bytes (see below) - */ - if( len < 3 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * First byte is curve_type; only named_curve is handled - */ - if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * Next two bytes are the namedcurve value - */ - tls_id = *(*buf)++; - tls_id <<= 8; - tls_id |= *(*buf)++; - - if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - *grp = curve_info->grp_id; - - return( 0 ); -} - -/* - * Write the ECParameters record corresponding to a group (RFC 4492) - */ -int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, - unsigned char *buf, size_t blen ) -{ - const mbedtls_ecp_curve_info *curve_info; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - - if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * We are going to write 3 bytes (see below) - */ - *olen = 3; - if( blen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - /* - * First byte is curve_type, always named_curve - */ - *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE; - - /* - * Next two bytes are the namedcurve value - */ - buf[0] = curve_info->tls_id >> 8; - buf[1] = curve_info->tls_id & 0xFF; - - return( 0 ); -} - -/* - * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi. - * See the documentation of struct mbedtls_ecp_group. - * - * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf. - */ -static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp ) -{ - int ret; - - if( grp->modp == NULL ) - return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) ); - - /* N->s < 0 is a much faster test, which fails only if N is 0 */ - if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) || - mbedtls_mpi_bitlen( N ) > 2 * grp->pbits ) - { - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - MBEDTLS_MPI_CHK( grp->modp( N ) ); - - /* N->s < 0 is a much faster test, which fails only if N is 0 */ - while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) ); - - while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 ) - /* we known P, N and the result are positive */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) ); - -cleanup: - return( ret ); -} - -/* - * Fast mod-p functions expect their argument to be in the 0..p^2 range. - * - * In order to guarantee that, we need to ensure that operands of - * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will - * bring the result back to this range. - * - * The following macros are shortcuts for doing that. - */ - -/* - * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi - */ -#if defined(MBEDTLS_SELF_TEST) -#define INC_MUL_COUNT mul_count++; -#else -#define INC_MUL_COUNT -#endif - -#define MOD_MUL( N ) \ - do \ - { \ - MBEDTLS_MPI_CHK( ecp_modp( &(N), grp ) ); \ - INC_MUL_COUNT \ - } while( 0 ) - -/* - * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi - * N->s < 0 is a very fast test, which fails only if N is 0 - */ -#define MOD_SUB( N ) \ - while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) ) - -/* - * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. - * We known P, N and the result are positive, so sub_abs is correct, and - * a bit faster. - */ -#define MOD_ADD( N ) \ - while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) ) - -#if defined(ECP_SHORTWEIERSTRASS) -/* - * For curves in short Weierstrass form, we do all the internal operations in - * Jacobian coordinates. - * - * For multiplication, we'll use a comb method with coutermeasueres against - * SPA, hence timing attacks. - */ - -/* - * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) - * Cost: 1N := 1I + 3M + 1S - */ -static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt ) -{ - int ret; - mbedtls_mpi Zi, ZZi; - - if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ) - return( 0 ); - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_jac( grp, pt ) ); -#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ - - mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); - - /* - * X = X / Z^2 mod p - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X ); - - /* - * Y = Y / Z^3 mod p - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y ); - - /* - * Z = 1 - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); - -cleanup: - - mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); - - return( ret ); -} - -/* - * Normalize jacobian coordinates of an array of (pointers to) points, - * using Montgomery's trick to perform only one inversion mod P. - * (See for example Cohen's "A Course in Computational Algebraic Number - * Theory", Algorithm 10.3.4.) - * - * Warning: fails (returning an error) if one of the points is zero! - * This should never happen, see choice of w in ecp_mul_comb(). - * - * Cost: 1N(t) := 1I + (6t - 3)M + 1S - */ -static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *T[], size_t T_size ) -{ - int ret; - size_t i; - mbedtls_mpi *c, u, Zi, ZZi; - - if( T_size < 2 ) - return( ecp_normalize_jac( grp, *T ) ); - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) ); -#endif - - if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL ) - return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); - - for( i = 0; i < T_size; i++ ) - mbedtls_mpi_init( &c[i] ); - - mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); - - /* - * c[i] = Z_0 * ... * Z_i - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) ); - for( i = 1; i < T_size; i++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); - MOD_MUL( c[i] ); - } - - /* - * u = 1 / (Z_0 * ... * Z_n) mod P - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[T_size-1], &grp->P ) ); - - for( i = T_size - 1; ; i-- ) - { - /* - * Zi = 1 / Z_i mod p - * u = 1 / (Z_0 * ... * Z_i) mod P - */ - if( i == 0 ) { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u ); - } - - /* - * proceed as in normalize() - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y ); - - /* - * Post-precessing: reclaim some memory by shrinking coordinates - * - not storing Z (always 1) - * - shrinking other coordinates, but still keeping the same number of - * limbs as P, as otherwise it will too likely be regrown too fast. - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) ); - mbedtls_mpi_free( &T[i]->Z ); - - if( i == 0 ) - break; - } - -cleanup: - - mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); - for( i = 0; i < T_size; i++ ) - mbedtls_mpi_free( &c[i] ); - mbedtls_free( c ); - - return( ret ); -} - -/* - * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. - * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid - */ -static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *Q, - unsigned char inv ) -{ - int ret; - unsigned char nonzero; - mbedtls_mpi mQY; - - mbedtls_mpi_init( &mQY ); - - /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) ); - nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) ); - -cleanup: - mbedtls_mpi_free( &mQY ); - - return( ret ); -} - -/* - * Point doubling R = 2 P, Jacobian coordinates - * - * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 . - * - * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR - * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring. - * - * Standard optimizations are applied when curve parameter A is one of { 0, -3 }. - * - * Cost: 1D := 3M + 4S (A == 0) - * 4M + 4S (A == -3) - * 3M + 6S + 1a otherwise - */ -static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P ) -{ - int ret; - mbedtls_mpi M, S, T, U; - -#if defined(MBEDTLS_SELF_TEST) - dbl_count++; -#endif - -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_double_jac( grp, R, P ) ); -#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ - - mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U ); - - /* Special case for A = -3 */ - if( grp->A.p == NULL ) - { - /* M = 3(X + Z^2)(X - Z^2) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); - } - else - { - /* M = 3.X^2 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); - - /* Optimize away for "koblitz" curves with A = 0 */ - if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 ) - { - /* M += A.Z^4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M ); - } - } - - /* S = 4.X.Y^2 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S ); - - /* U = 8.Y^4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); - - /* T = M^2 - 2.S */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); - - /* S = M(S - T) - U */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S ); - - /* U = 2.Y.Z */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) ); - -cleanup: - mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U ); - - return( ret ); -} - -/* - * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) - * - * The coordinates of Q must be normalized (= affine), - * but those of P don't need to. R is not normalized. - * - * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. - * None of these cases can happen as intermediate step in ecp_mul_comb(): - * - at each step, P, Q and R are multiples of the base point, the factor - * being less than its order, so none of them is zero; - * - Q is an odd multiple of the base point, P an even multiple, - * due to the choice of precomputed points in the modified comb method. - * So branches for these cases do not leak secret information. - * - * We accept Q->Z being unset (saving memory in tables) as meaning 1. - * - * Cost: 1A := 8M + 3S - */ -static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) -{ - int ret; - mbedtls_mpi T1, T2, T3, T4, X, Y, Z; - -#if defined(MBEDTLS_SELF_TEST) - add_count++; -#endif - -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) ); -#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ - - /* - * Trivial cases: P == 0 or Q == 0 (case 1) - */ - if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) - return( mbedtls_ecp_copy( R, Q ) ); - - if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 ) - return( mbedtls_ecp_copy( R, P ) ); - - /* - * Make sure Q coordinates are normalized - */ - if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 ); - mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 ); - - /* Special cases (2) and (3) */ - if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 ) - { - if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 ) - { - ret = ecp_double_jac( grp, R, P ); - goto cleanup; - } - else - { - ret = mbedtls_ecp_set_zero( R ); - goto cleanup; - } - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) ); - -cleanup: - - mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 ); - mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); - - return( ret ); -} - -/* - * Randomize jacobian coordinates: - * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l - * This is sort of the reverse operation of ecp_normalize_jac(). - * - * This countermeasure was first suggested in [2]. - */ -static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_mpi l, ll; - size_t p_size; - int count = 0; - -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) ); -#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ - - p_size = ( grp->pbits + 7 ) / 8; - mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll ); - - /* Generate l such that 1 < l < p */ - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); - - while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); - - if( count++ > 10 ) - return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); - } - while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ); - - /* Z = l * Z */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z ); - - /* X = l^2 * X */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X ); - - /* Y = l^3 * Y */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y ); - -cleanup: - mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll ); - - return( ret ); -} - -/* - * Check and define parameters used by the comb method (see below for details) - */ -#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7 -#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds" -#endif - -/* d = ceil( n / w ) */ -#define COMB_MAX_D ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2 - -/* number of precomputed points */ -#define COMB_MAX_PRE ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) - -/* - * Compute the representation of m that will be used with our comb method. - * - * The basic comb method is described in GECC 3.44 for example. We use a - * modified version that provides resistance to SPA by avoiding zero - * digits in the representation as in [3]. We modify the method further by - * requiring that all K_i be odd, which has the small cost that our - * representation uses one more K_i, due to carries, but saves on the size of - * the precomputed table. - * - * Summary of the comb method and its modifications: - * - * - The goal is to compute m*P for some w*d-bit integer m. - * - * - The basic comb method splits m into the w-bit integers - * x[0] .. x[d-1] where x[i] consists of the bits in m whose - * index has residue i modulo d, and computes m * P as - * S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where - * S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P. - * - * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by - * .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] .., - * thereby successively converting it into a form where all summands - * are nonzero, at the cost of negative summands. This is the basic idea of [3]. - * - * - More generally, even if x[i+1] != 0, we can first transform the sum as - * .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] .., - * and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]]. - * Performing and iterating this procedure for those x[i] that are even - * (keeping track of carry), we can transform the original sum into one of the form - * S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]] - * with all x'[i] odd. It is therefore only necessary to know S at odd indices, - * which is why we are only computing half of it in the first place in - * ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb. - * - * - For the sake of compactness, only the seven low-order bits of x[i] - * are used to represent its absolute value (K_i in the paper), and the msb - * of x[i] encodes the sign (s_i in the paper): it is set if and only if - * if s_i == -1; - * - * Calling conventions: - * - x is an array of size d + 1 - * - w is the size, ie number of teeth, of the comb, and must be between - * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE) - * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d - * (the result will be incorrect if these assumptions are not satisfied) - */ -static void ecp_comb_recode_core( unsigned char x[], size_t d, - unsigned char w, const mbedtls_mpi *m ) -{ - size_t i, j; - unsigned char c, cc, adjust; - - memset( x, 0, d+1 ); - - /* First get the classical comb values (except for x_d = 0) */ - for( i = 0; i < d; i++ ) - for( j = 0; j < w; j++ ) - x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j; - - /* Now make sure x_1 .. x_d are odd */ - c = 0; - for( i = 1; i <= d; i++ ) - { - /* Add carry and update it */ - cc = x[i] & c; - x[i] = x[i] ^ c; - c = cc; - - /* Adjust if needed, avoiding branches */ - adjust = 1 - ( x[i] & 0x01 ); - c |= x[i] & ( x[i-1] * adjust ); - x[i] = x[i] ^ ( x[i-1] * adjust ); - x[i-1] |= adjust << 7; - } -} - -/* - * Precompute points for the adapted comb method - * - * Assumption: T must be able to hold 2^{w - 1} elements. - * - * Operation: If i = i_{w-1} ... i_1 is the binary representation of i, - * sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P. - * - * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) - * - * Note: Even comb values (those where P would be omitted from the - * sum defining T[i] above) are not needed in our adaption - * the comb method. See ecp_comb_recode_core(). - * - * This function currently works in four steps: - * (1) [dbl] Computation of intermediate T[i] for 2-power values of i - * (2) [norm_dbl] Normalization of coordinates of these T[i] - * (3) [add] Computation of all T[i] - * (4) [norm_add] Normalization of all T[i] - * - * Step 1 can be interrupted but not the others; together with the final - * coordinate normalization they are the largest steps done at once, depending - * on the window size. Here are operation counts for P-256: - * - * step (2) (3) (4) - * w = 5 142 165 208 - * w = 4 136 77 160 - * w = 3 130 33 136 - * w = 2 124 11 124 - * - * So if ECC operations are blocking for too long even with a low max_ops - * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order - * to minimize maximum blocking time. - */ -static int ecp_precompute_comb( const mbedtls_ecp_group *grp, - mbedtls_ecp_point T[], const mbedtls_ecp_point *P, - unsigned char w, size_t d, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char i; - size_t j = 0; - const unsigned char T_size = 1U << ( w - 1 ); - mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1]; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) - goto dbl; - if( rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl ) - goto norm_dbl; - if( rs_ctx->rsm->state == ecp_rsm_pre_add ) - goto add; - if( rs_ctx->rsm->state == ecp_rsm_pre_norm_add ) - goto norm_add; - } -#else - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - rs_ctx->rsm->state = ecp_rsm_pre_dbl; - - /* initial state for the loop */ - rs_ctx->rsm->i = 0; - } - -dbl: -#endif - /* - * Set T[0] = P and - * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) - j = rs_ctx->rsm->i; - else -#endif - j = 0; - - for( ; j < d * ( w - 1 ); j++ ) - { - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL ); - - i = 1U << ( j / d ); - cur = T + i; - - if( j % d == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) ); - - MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) ); - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl; - -norm_dbl: -#endif - /* - * Normalize current elements in T. As T has holes, - * use an auxiliary array of pointers to elements in T. - */ - j = 0; - for( i = 1; i < T_size; i <<= 1 ) - TT[j++] = T + i; - - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); - - MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_add; - -add: -#endif - /* - * Compute the remaining ones using the minimal number of additions - * Be careful to update T[2^l] only after using it! - */ - MBEDTLS_ECP_BUDGET( ( T_size - 1 ) * MBEDTLS_ECP_OPS_ADD ); - - for( i = 1; i < T_size; i <<= 1 ) - { - j = i; - while( j-- ) - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_norm_add; - -norm_add: -#endif - /* - * Normalize final elements in T. Even though there are no holes now, we - * still need the auxiliary array for homogeneity with the previous - * call. Also, skip T[0] which is already normalised, being a copy of P. - */ - for( j = 0; j + 1 < T_size; j++ ) - TT[j] = T + j + 1; - - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); - - MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); - -cleanup: -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) - rs_ctx->rsm->i = j; - } -#endif - - return( ret ); -} - -/* - * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] - * - * See ecp_comb_recode_core() for background - */ -static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, - unsigned char i ) -{ - int ret; - unsigned char ii, j; - - /* Ignore the "sign" bit and scale down */ - ii = ( i & 0x7Fu ) >> 1; - - /* Read the whole table to thwart cache-based timing attacks */ - for( j = 0; j < T_size; j++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); - } - - /* Safely invert result if i is "negative" */ - MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) ); - -cleanup: - return( ret ); -} - -/* - * Core multiplication algorithm for the (modified) comb method. - * This part is actually common with the basic comb method (GECC 3.44) - * - * Cost: d A + d D + 1 R - */ -static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, - const unsigned char x[], size_t d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_ecp_point Txi; - size_t i; - - mbedtls_ecp_point_init( &Txi ); - -#if !defined(MBEDTLS_ECP_RESTARTABLE) - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - rs_ctx->rsm->state != ecp_rsm_comb_core ) - { - rs_ctx->rsm->i = 0; - rs_ctx->rsm->state = ecp_rsm_comb_core; - } - - /* new 'if' instead of nested for the sake of the 'else' branch */ - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) - { - /* restore current index (R already pointing to rs_ctx->rsm->R) */ - i = rs_ctx->rsm->i; - } - else -#endif - { - /* Start with a non-zero point and randomize its coordinates */ - i = d; - MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) ); - if( f_rng != 0 ) - MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); - } - - while( i != 0 ) - { - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD ); - --i; - - MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) ); - MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, T_size, x[i] ) ); - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); - } - -cleanup: - - mbedtls_ecp_point_free( &Txi ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - rs_ctx->rsm->i = i; - /* no need to save R, already pointing to rs_ctx->rsm->R */ - } -#endif - - return( ret ); -} - -/* - * Recode the scalar to get constant-time comb multiplication - * - * As the actual scalar recoding needs an odd scalar as a starting point, - * this wrapper ensures that by replacing m by N - m if necessary, and - * informs the caller that the result of multiplication will be negated. - * - * This works because we only support large prime order for Short Weierstrass - * curves, so N is always odd hence either m or N - m is. - * - * See ecp_comb_recode_core() for background. - */ -static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp, - const mbedtls_mpi *m, - unsigned char k[COMB_MAX_D + 1], - size_t d, - unsigned char w, - unsigned char *parity_trick ) -{ - int ret; - mbedtls_mpi M, mm; - - mbedtls_mpi_init( &M ); - mbedtls_mpi_init( &mm ); - - /* N is always odd (see above), just make extra sure */ - if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* do we need the parity trick? */ - *parity_trick = ( mbedtls_mpi_get_bit( m, 0 ) == 0 ); - - /* execute parity fix in constant time */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, *parity_trick ) ); - - /* actual scalar recoding */ - ecp_comb_recode_core( k, d, w, &M ); - -cleanup: - mbedtls_mpi_free( &mm ); - mbedtls_mpi_free( &M ); - - return( ret ); -} - -/* - * Perform comb multiplication (for short Weierstrass curves) - * once the auxiliary table has been pre-computed. - * - * Scalar recoding may use a parity trick that makes us compute -m * P, - * if that is the case we'll need to recover m * P at the end. - */ -static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - const mbedtls_mpi *m, - const mbedtls_ecp_point *T, - unsigned char T_size, - unsigned char w, - size_t d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char parity_trick; - unsigned char k[COMB_MAX_D + 1]; - mbedtls_ecp_point *RR = R; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - RR = &rs_ctx->rsm->R; - - if( rs_ctx->rsm->state == ecp_rsm_final_norm ) - goto final_norm; - } -#endif - - MBEDTLS_MPI_CHK( ecp_comb_recode_scalar( grp, m, k, d, w, - &parity_trick ) ); - MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, RR, T, T_size, k, d, - f_rng, p_rng, rs_ctx ) ); - MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, RR, parity_trick ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_final_norm; - -final_norm: -#endif - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); - MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, RR ) ); -#endif - -cleanup: - return( ret ); -} - -/* - * Pick window size based on curve size and whether we optimize for base point - */ -static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp, - unsigned char p_eq_g ) -{ - unsigned char w; - - /* - * Minimize the number of multiplications, that is minimize - * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) - * (see costs of the various parts, with 1S = 1M) - */ - w = grp->nbits >= 384 ? 5 : 4; - - /* - * If P == G, pre-compute a bit more, since this may be re-used later. - * Just adding one avoids upping the cost of the first mul too much, - * and the memory cost too. - */ - if( p_eq_g ) - w++; - - /* - * Make sure w is within bounds. - * (The last test is useful only for very small curves in the test suite.) - */ - if( w > MBEDTLS_ECP_WINDOW_SIZE ) - w = MBEDTLS_ECP_WINDOW_SIZE; - if( w >= grp->nbits ) - w = 2; - - return( w ); -} - -/* - * Multiplication using the comb method - for curves in short Weierstrass form - * - * This function is mainly responsible for administrative work: - * - managing the restart context if enabled - * - managing the table of precomputed points (passed between the below two - * functions): allocation, computation, ownership tranfer, freeing. - * - * It delegates the actual arithmetic work to: - * ecp_precompute_comb() and ecp_mul_comb_with_precomp() - * - * See comments on ecp_comb_recode_core() regarding the computation strategy. - */ -static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char w, p_eq_g, i; - size_t d; - unsigned char T_size, T_ok; - mbedtls_ecp_point *T; - - ECP_RS_ENTER( rsm ); - - /* Is P the base point ? */ -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 - p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && - mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); -#else - p_eq_g = 0; -#endif - - /* Pick window size and deduce related sizes */ - w = ecp_pick_window_size( grp, p_eq_g ); - T_size = 1U << ( w - 1 ); - d = ( grp->nbits + w - 1 ) / w; - - /* Pre-computed table: do we have it already for the base point? */ - if( p_eq_g && grp->T != NULL ) - { - /* second pointer to the same table, will be deleted on exit */ - T = grp->T; - T_ok = 1; - } - else -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* Pre-computed table: do we have one in progress? complete? */ - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL ) - { - /* transfer ownership of T from rsm to local function */ - T = rs_ctx->rsm->T; - rs_ctx->rsm->T = NULL; - rs_ctx->rsm->T_size = 0; - - /* This effectively jumps to the call to mul_comb_after_precomp() */ - T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core; - } - else -#endif - /* Allocate table if we didn't have any */ - { - T = mbedtls_calloc( T_size, sizeof( mbedtls_ecp_point ) ); - if( T == NULL ) - { - ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; - goto cleanup; - } - - for( i = 0; i < T_size; i++ ) - mbedtls_ecp_point_init( &T[i] ); - - T_ok = 0; - } - - /* Compute table (or finish computing it) if not done already */ - if( !T_ok ) - { - MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d, rs_ctx ) ); - - if( p_eq_g ) - { - /* almost transfer ownership of T to the group, but keep a copy of - * the pointer to use for calling the next function more easily */ - grp->T = T; - grp->T_size = T_size; - } - } - - /* Actual comb multiplication using precomputed points */ - MBEDTLS_MPI_CHK( ecp_mul_comb_after_precomp( grp, R, m, - T, T_size, w, d, - f_rng, p_rng, rs_ctx ) ); - -cleanup: - - /* does T belong to the group? */ - if( T == grp->T ) - T = NULL; - - /* does T belong to the restart context? */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL ) - { - /* transfer ownership of T from local function to rsm */ - rs_ctx->rsm->T_size = T_size; - rs_ctx->rsm->T = T; - T = NULL; - } -#endif - - /* did T belong to us? then let's destroy it! */ - if( T != NULL ) - { - for( i = 0; i < T_size; i++ ) - mbedtls_ecp_point_free( &T[i] ); - mbedtls_free( T ); - } - - /* don't free R while in progress in case R == P */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif - /* prevent caller from using invalid value */ - if( ret != 0 ) - mbedtls_ecp_point_free( R ); - - ECP_RS_LEAVE( rsm ); - - return( ret ); -} - -#endif /* ECP_SHORTWEIERSTRASS */ - -#if defined(ECP_MONTGOMERY) -/* - * For Montgomery curves, we do all the internal arithmetic in projective - * coordinates. Import/export of points uses only the x coordinates, which is - * internaly represented as X / Z. - * - * For scalar multiplication, we'll use a Montgomery ladder. - */ - -/* - * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 - * Cost: 1M + 1I - */ -static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P ) -{ - int ret; - -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_mxz( grp, P ) ); -#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); - -cleanup: - return( ret ); -} - -/* - * Randomize projective x/z coordinates: - * (X, Z) -> (l X, l Z) for random l - * This is sort of the reverse operation of ecp_normalize_mxz(). - * - * This countermeasure was first suggested in [2]. - * Cost: 2M - */ -static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_mpi l; - size_t p_size; - int count = 0; - -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ); -#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ - - p_size = ( grp->pbits + 7 ) / 8; - mbedtls_mpi_init( &l ); - - /* Generate l such that 1 < l < p */ - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); - - while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); - - if( count++ > 10 ) - return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); - } - while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z ); - -cleanup: - mbedtls_mpi_free( &l ); - - return( ret ); -} - -/* - * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), - * for Montgomery curves in x/z coordinates. - * - * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 - * with - * d = X1 - * P = (X2, Z2) - * Q = (X3, Z3) - * R = (X4, Z4) - * S = (X5, Z5) - * and eliminating temporary variables tO, ..., t4. - * - * Cost: 5M + 4S - */ -static int ecp_double_add_mxz( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, mbedtls_ecp_point *S, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, - const mbedtls_mpi *d ) -{ - int ret; - mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB; - -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) ); -#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ - - mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B ); - mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C ); - mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z ); - -cleanup: - mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B ); - mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C ); - mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB ); - - return( ret ); -} - -/* - * Multiplication with Montgomery ladder in x/z coordinates, - * for curves in Montgomery form - */ -static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t i; - unsigned char b; - mbedtls_ecp_point RP; - mbedtls_mpi PX; - - mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX ); - - /* Save PX and read from P before writing to R, in case P == R */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) ); - - /* Set R to zero in modified x/z coordinates */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) ); - mbedtls_mpi_free( &R->Y ); - - /* RP.X might be sligtly larger than P, so reduce it */ - MOD_ADD( RP.X ); - - /* Randomize coordinates of the starting point */ - if( f_rng != NULL ) - MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); - - /* Loop invariant: R = result so far, RP = R + P */ - i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */ - while( i-- > 0 ) - { - b = mbedtls_mpi_get_bit( m, i ); - /* - * if (b) R = 2R + P else R = 2R, - * which is: - * if (b) double_add( RP, R, RP, R ) - * else double_add( R, RP, R, RP ) - * but using safe conditional swaps to avoid leaks - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); - MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); - } - - MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); - -cleanup: - mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX ); - - return( ret ); -} - -#endif /* ECP_MONTGOMERY */ - -/* - * Restartable multiplication R = m * P - */ -int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* reset ops count for this call if top-level */ - if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) - rs_ctx->ops_done = 0; -#endif - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) - MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* skip argument check when restarting */ - if( rs_ctx == NULL || rs_ctx->rsm == NULL ) -#endif - { - /* check_privkey is free */ - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK ); - - /* Common sanity checks */ - MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); - } - - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(ECP_MONTGOMERY) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) ); -#endif - -cleanup: - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( is_grp_capable ) - mbedtls_internal_ecp_free( grp ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL ) - rs_ctx->depth--; -#endif - - return( ret ); -} - -/* - * Multiplication R = m * P - */ -int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) ); -} - -#if defined(ECP_SHORTWEIERSTRASS) -/* - * Check that an affine point is valid as a public key, - * short weierstrass curves (SEC1 3.2.3.1) - */ -static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) -{ - int ret; - mbedtls_mpi YY, RHS; - - /* pt coordinates must be normalized for our checks */ - if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 || - mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 || - mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || - mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS ); - - /* - * YY = Y^2 - * RHS = X (X^2 + A) + B = X^3 + A X + B - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); - - /* Special case for A = -3 */ - if( grp->A.p == NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); - - if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 ) - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - -cleanup: - - mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS ); - - return( ret ); -} -#endif /* ECP_SHORTWEIERSTRASS */ - -/* - * R = m * P with shortcuts for m == 1 and m == -1 - * NOT constant-time - ONLY for short Weierstrass! - */ -static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - const mbedtls_mpi *m, - const mbedtls_ecp_point *P, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - - if( mbedtls_mpi_cmp_int( m, 1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); - } - else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); - if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P, - NULL, NULL, rs_ctx ) ); - } - -cleanup: - return( ret ); -} - -/* - * Restartable linear combination - * NOT constant-time - */ -int mbedtls_ecp_muladd_restartable( - mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_ecp_point mP; - mbedtls_ecp_point *pmP = &mP; - mbedtls_ecp_point *pR = R; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( n != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - - if( mbedtls_ecp_get_type( grp ) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - mbedtls_ecp_point_init( &mP ); - - ECP_RS_ENTER( ma ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - { - /* redirect intermediate results to restart context */ - pmP = &rs_ctx->ma->mP; - pR = &rs_ctx->ma->R; - - /* jump to next operation */ - if( rs_ctx->ma->state == ecp_rsma_mul2 ) - goto mul2; - if( rs_ctx->ma->state == ecp_rsma_add ) - goto add; - if( rs_ctx->ma->state == ecp_rsma_norm ) - goto norm; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pmP, m, P, rs_ctx ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_mul2; - -mul2: -#endif - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR, n, Q, rs_ctx ) ); - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) - MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_add; - -add: -#endif - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_ADD ); - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_norm; - -norm: -#endif - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); - MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, pR ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, pR ) ); -#endif - -cleanup: -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( is_grp_capable ) - mbedtls_internal_ecp_free( grp ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - - mbedtls_ecp_point_free( &mP ); - - ECP_RS_LEAVE( ma ); - - return( ret ); -} - -/* - * Linear combination - * NOT constant-time - */ -int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( n != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) ); -} - -#if defined(ECP_MONTGOMERY) -/* - * Check validity of a public key for Montgomery curves with x-only schemes - */ -static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) -{ - /* [Curve25519 p. 5] Just check X is the correct number of bytes */ - /* Allow any public value, if it's too big then we'll just reduce it mod p - * (RFC 7748 sec. 5 para. 3). */ - if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - return( 0 ); -} -#endif /* ECP_MONTGOMERY */ - -/* - * Check that a point is valid as a public key - */ -int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - - /* Must use affine coordinates */ - if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - -#if defined(ECP_MONTGOMERY) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - return( ecp_check_pubkey_mx( grp, pt ) ); -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - return( ecp_check_pubkey_sw( grp, pt ) ); -#endif - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); -} - -/* - * Check that an mbedtls_mpi is valid as a private key - */ -int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, - const mbedtls_mpi *d ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - -#if defined(ECP_MONTGOMERY) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - { - /* see RFC 7748 sec. 5 para. 5 */ - if( mbedtls_mpi_get_bit( d, 0 ) != 0 || - mbedtls_mpi_get_bit( d, 1 ) != 0 || - mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */ - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - /* see [Curve25519] page 5 */ - if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - return( 0 ); - } -#endif /* ECP_MONTGOMERY */ -#if defined(ECP_SHORTWEIERSTRASS) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - { - /* see SEC1 3.2 */ - if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || - mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - else - return( 0 ); - } -#endif /* ECP_SHORTWEIERSTRASS */ - - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); -} - -/* - * Generate a private key - */ -int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, - mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - size_t n_size; - - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - n_size = ( grp->nbits + 7 ) / 8; - -#if defined(ECP_MONTGOMERY) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - { - /* [M225] page 5 */ - size_t b; - - do { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); - } while( mbedtls_mpi_bitlen( d ) == 0); - - /* Make sure the most significant bit is nbits */ - b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */ - if( b > grp->nbits ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) ); - else - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) ); - - /* Make sure the last two bits are unset for Curve448, three bits for - Curve25519 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) ); - if( grp->nbits == 254 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); - } - } -#endif /* ECP_MONTGOMERY */ - -#if defined(ECP_SHORTWEIERSTRASS) - if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - { - /* SEC1 3.2.1: Generate d such that 1 <= n < N */ - int count = 0; - - /* - * Match the procedure given in RFC 6979 (deterministic ECDSA): - * - use the same byte ordering; - * - keep the leftmost nbits bits of the generated octet string; - * - try until result is in the desired range. - * This also avoids any biais, which is especially important for ECDSA. - */ - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) ); - - /* - * Each try has at worst a probability 1/2 of failing (the msb has - * a probability 1/2 of being 0, and then the result will be < N), - * so after 30 tries failure probability is a most 2**(-30). - * - * For most curves, 1 try is enough with overwhelming probability, - * since N starts with a lot of 1s in binary, but some curves - * such as secp224k1 are actually very close to the worst case. - */ - if( ++count > 30 ) - return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); - } - while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || - mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ); - } -#endif /* ECP_SHORTWEIERSTRASS */ - -cleanup: - return( ret ); -} - -/* - * Generate a keypair with configurable base point - */ -int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( G != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); - -cleanup: - return( ret ); -} - -/* - * Generate key pair, wrapper for conventional base point - */ -int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) ); -} - -/* - * Generate a keypair, prettier wrapper - */ -int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - ECP_VALIDATE_RET( key != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) - return( ret ); - - return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); -} - -#define ECP_CURVE25519_KEY_SIZE 32 -/* - * Read a private key. - */ -int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - const unsigned char *buf, size_t buflen ) -{ - int ret = 0; - - ECP_VALIDATE_RET( key != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - - if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) - return( ret ); - - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - -#if defined(ECP_MONTGOMERY) - if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY ) - { - /* - * If it is Curve25519 curve then mask the key as mandated by RFC7748 - */ - if( grp_id == MBEDTLS_ECP_DP_CURVE25519 ) - { - if( buflen != ECP_CURVE25519_KEY_SIZE ) - return MBEDTLS_ERR_ECP_INVALID_KEY; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) ); - - /* Set the three least significant bits to 0 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) ); - - /* Set the most significant bit to 0 */ - MBEDTLS_MPI_CHK( - mbedtls_mpi_set_bit( &key->d, - ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 ) - ); - - /* Set the second most significant bit to 1 */ - MBEDTLS_MPI_CHK( - mbedtls_mpi_set_bit( &key->d, - ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 ) - ); - } - else - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } - -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( &key->grp, &key->d ) ); - } - -#endif -cleanup: - - if( ret != 0 ) - mbedtls_mpi_free( &key->d ); - - return( ret ); -} - -/* - * Check a public-private key pair - */ -int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ) -{ - int ret; - mbedtls_ecp_point Q; - mbedtls_ecp_group grp; - ECP_VALIDATE_RET( pub != NULL ); - ECP_VALIDATE_RET( prv != NULL ); - - if( pub->grp.id == MBEDTLS_ECP_DP_NONE || - pub->grp.id != prv->grp.id || - mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) || - mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) || - mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) ) - { - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - mbedtls_ecp_point_init( &Q ); - mbedtls_ecp_group_init( &grp ); - - /* mbedtls_ecp_mul() needs a non-const group... */ - mbedtls_ecp_group_copy( &grp, &prv->grp ); - - /* Also checks d is valid */ - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) ); - - if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) || - mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) || - mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free( &Q ); - mbedtls_ecp_group_free( &grp ); - - return( ret ); -} - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Checkup routine - */ -int mbedtls_ecp_self_test( int verbose ) -{ - int ret; - size_t i; - mbedtls_ecp_group grp; - mbedtls_ecp_point R, P; - mbedtls_mpi m; - unsigned long add_c_prev, dbl_c_prev, mul_c_prev; - /* exponents especially adapted for secp192r1 */ - const char *exponents[] = - { - "000000000000000000000000000000000000000000000001", /* one */ - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ - "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ - "400000000000000000000000000000000000000000000000", /* one and zeros */ - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ - "555555555555555555555555555555555555555555555555", /* 101010... */ - }; - - mbedtls_ecp_group_init( &grp ); - mbedtls_ecp_point_init( &R ); - mbedtls_ecp_point_init( &P ); - mbedtls_mpi_init( &m ); - - /* Use secp192r1 if available, or any available curve */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) ); -#else - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) ); -#endif - - if( verbose != 0 ) - mbedtls_printf( " ECP test #1 (constant op_count, base point G): " ); - - /* Do a dummy multiplication first to trigger precomputation */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) ); - - add_count = 0; - dbl_count = 0; - mul_count = 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); - - for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) - { - add_c_prev = add_count; - dbl_c_prev = dbl_count; - mul_c_prev = mul_count; - add_count = 0; - dbl_count = 0; - mul_count = 0; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); - - if( add_count != add_c_prev || - dbl_count != dbl_c_prev || - mul_count != mul_c_prev ) - { - if( verbose != 0 ) - mbedtls_printf( "failed (%u)\n", (unsigned int) i ); - - ret = 1; - goto cleanup; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " ECP test #2 (constant op_count, other point): " ); - /* We computed P = 2G last time, use it */ - - add_count = 0; - dbl_count = 0; - mul_count = 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); - - for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) - { - add_c_prev = add_count; - dbl_c_prev = dbl_count; - mul_c_prev = mul_count; - add_count = 0; - dbl_count = 0; - mul_count = 0; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); - - if( add_count != add_c_prev || - dbl_count != dbl_c_prev || - mul_count != mul_c_prev ) - { - if( verbose != 0 ) - mbedtls_printf( "failed (%u)\n", (unsigned int) i ); - - ret = 1; - goto cleanup; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -cleanup: - - if( ret < 0 && verbose != 0 ) - mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); - - mbedtls_ecp_group_free( &grp ); - mbedtls_ecp_point_free( &R ); - mbedtls_ecp_point_free( &P ); - mbedtls_mpi_free( &m ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* !MBEDTLS_ECP_ALT */ - -#endif /* MBEDTLS_ECP_C */ diff --git a/library/ecp_curves.c b/library/ecp_curves.c deleted file mode 100644 index 282481d053..0000000000 --- a/library/ecp_curves.c +++ /dev/null @@ -1,1470 +0,0 @@ -/* - * Elliptic curves over GF(p): curve-specific data and functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECP_C) - -#include "mbedtls/ecp.h" -#include "mbedtls/platform_util.h" - -#include - -#if !defined(MBEDTLS_ECP_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define ECP_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECP_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* - * Conversion macros for embedded constants: - * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 - */ -#if defined(MBEDTLS_HAVE_INT32) - -#define BYTES_TO_T_UINT_4( a, b, c, d ) \ - ( (mbedtls_mpi_uint) (a) << 0 ) | \ - ( (mbedtls_mpi_uint) (b) << 8 ) | \ - ( (mbedtls_mpi_uint) (c) << 16 ) | \ - ( (mbedtls_mpi_uint) (d) << 24 ) - -#define BYTES_TO_T_UINT_2( a, b ) \ - BYTES_TO_T_UINT_4( a, b, 0, 0 ) - -#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ - BYTES_TO_T_UINT_4( a, b, c, d ), \ - BYTES_TO_T_UINT_4( e, f, g, h ) - -#else /* 64-bits */ - -#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ - ( (mbedtls_mpi_uint) (a) << 0 ) | \ - ( (mbedtls_mpi_uint) (b) << 8 ) | \ - ( (mbedtls_mpi_uint) (c) << 16 ) | \ - ( (mbedtls_mpi_uint) (d) << 24 ) | \ - ( (mbedtls_mpi_uint) (e) << 32 ) | \ - ( (mbedtls_mpi_uint) (f) << 40 ) | \ - ( (mbedtls_mpi_uint) (g) << 48 ) | \ - ( (mbedtls_mpi_uint) (h) << 56 ) - -#define BYTES_TO_T_UINT_4( a, b, c, d ) \ - BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) - -#define BYTES_TO_T_UINT_2( a, b ) \ - BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) - -#endif /* bits in mbedtls_mpi_uint */ - -/* - * Note: the constants are in little-endian order - * to be directly usable in MPIs - */ - -/* - * Domain parameters for secp192r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static const mbedtls_mpi_uint secp192r1_p[] = { - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp192r1_b[] = { - BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), - BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), - BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), -}; -static const mbedtls_mpi_uint secp192r1_gx[] = { - BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), - BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), - BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), -}; -static const mbedtls_mpi_uint secp192r1_gy[] = { - BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), - BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), - BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), -}; -static const mbedtls_mpi_uint secp192r1_n[] = { - BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), - BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -/* - * Domain parameters for secp224r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static const mbedtls_mpi_uint secp224r1_p[] = { - BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), - BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp224r1_b[] = { - BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), - BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), - BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), - BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), -}; -static const mbedtls_mpi_uint secp224r1_gx[] = { - BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), - BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), - BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), - BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), -}; -static const mbedtls_mpi_uint secp224r1_gy[] = { - BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), - BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), - BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), - BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), -}; -static const mbedtls_mpi_uint secp224r1_n[] = { - BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), - BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -/* - * Domain parameters for secp256r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static const mbedtls_mpi_uint secp256r1_p[] = { - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), - BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), - BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp256r1_b[] = { - BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), - BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), - BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), - BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), -}; -static const mbedtls_mpi_uint secp256r1_gx[] = { - BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), - BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), - BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), - BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), -}; -static const mbedtls_mpi_uint secp256r1_gy[] = { - BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), - BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), - BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), - BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), -}; -static const mbedtls_mpi_uint secp256r1_n[] = { - BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), - BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -/* - * Domain parameters for secp384r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static const mbedtls_mpi_uint secp384r1_p[] = { - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), - BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp384r1_b[] = { - BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), - BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), - BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), - BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), - BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), - BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), -}; -static const mbedtls_mpi_uint secp384r1_gx[] = { - BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), - BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), - BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), - BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), - BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), - BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), -}; -static const mbedtls_mpi_uint secp384r1_gy[] = { - BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), - BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), - BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), - BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), - BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), - BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), -}; -static const mbedtls_mpi_uint secp384r1_n[] = { - BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), - BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), - BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* - * Domain parameters for secp521r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static const mbedtls_mpi_uint secp521r1_p[] = { - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_2( 0xFF, 0x01 ), -}; -static const mbedtls_mpi_uint secp521r1_b[] = { - BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), - BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), - BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), - BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), - BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), - BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), - BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), - BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), - BYTES_TO_T_UINT_2( 0x51, 0x00 ), -}; -static const mbedtls_mpi_uint secp521r1_gx[] = { - BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), - BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), - BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), - BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), - BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), - BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), - BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), - BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), - BYTES_TO_T_UINT_2( 0xC6, 0x00 ), -}; -static const mbedtls_mpi_uint secp521r1_gy[] = { - BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), - BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), - BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), - BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), - BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), - BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), - BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), - BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), - BYTES_TO_T_UINT_2( 0x18, 0x01 ), -}; -static const mbedtls_mpi_uint secp521r1_n[] = { - BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), - BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), - BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), - BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), - BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_2( 0xFF, 0x01 ), -}; -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static const mbedtls_mpi_uint secp192k1_p[] = { - BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp192k1_a[] = { - BYTES_TO_T_UINT_2( 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp192k1_b[] = { - BYTES_TO_T_UINT_2( 0x03, 0x00 ), -}; -static const mbedtls_mpi_uint secp192k1_gx[] = { - BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), - BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), - BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), -}; -static const mbedtls_mpi_uint secp192k1_gy[] = { - BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), - BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), - BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), -}; -static const mbedtls_mpi_uint secp192k1_n[] = { - BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), - BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static const mbedtls_mpi_uint secp224k1_p[] = { - BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp224k1_a[] = { - BYTES_TO_T_UINT_2( 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp224k1_b[] = { - BYTES_TO_T_UINT_2( 0x05, 0x00 ), -}; -static const mbedtls_mpi_uint secp224k1_gx[] = { - BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), - BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), - BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), - BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), -}; -static const mbedtls_mpi_uint secp224k1_gy[] = { - BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), - BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), - BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), - BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), -}; -static const mbedtls_mpi_uint secp224k1_n[] = { - BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), - BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), - BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), - BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), -}; -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static const mbedtls_mpi_uint secp256k1_p[] = { - BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp256k1_a[] = { - BYTES_TO_T_UINT_2( 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp256k1_b[] = { - BYTES_TO_T_UINT_2( 0x07, 0x00 ), -}; -static const mbedtls_mpi_uint secp256k1_gx[] = { - BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), - BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), - BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), - BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), -}; -static const mbedtls_mpi_uint secp256k1_gy[] = { - BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), - BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), - BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), - BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), -}; -static const mbedtls_mpi_uint secp256k1_n[] = { - BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), - BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), - BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -/* - * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) - */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP256r1_p[] = { - BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), - BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), - BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), - BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_a[] = { - BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), - BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), - BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), - BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_b[] = { - BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), - BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), - BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), - BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { - BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), - BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), - BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), - BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { - BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), - BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), - BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), - BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_n[] = { - BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), - BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), - BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), - BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), -}; -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -/* - * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) - */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP384r1_p[] = { - BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), - BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), - BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), - BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), - BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), - BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_a[] = { - BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), - BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), - BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), - BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), - BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), - BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_b[] = { - BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), - BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), - BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), - BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), - BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), - BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { - BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), - BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), - BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), - BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), - BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), - BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { - BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), - BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), - BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), - BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), - BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), - BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_n[] = { - BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), - BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), - BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), - BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), - BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), - BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), -}; -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -/* - * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) - */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP512r1_p[] = { - BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), - BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), - BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), - BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), - BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), - BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), - BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), - BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_a[] = { - BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), - BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), - BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), - BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), - BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), - BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), - BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), - BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_b[] = { - BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), - BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), - BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), - BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), - BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), - BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), - BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), - BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { - BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), - BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), - BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), - BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), - BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), - BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), - BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), - BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { - BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), - BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), - BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), - BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), - BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), - BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), - BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), - BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_n[] = { - BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), - BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), - BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), - BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), - BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), - BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), - BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), - BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), -}; -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -/* - * Create an MPI from embedded constants - * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint) - */ -static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len ) -{ - X->s = 1; - X->n = len / sizeof( mbedtls_mpi_uint ); - X->p = (mbedtls_mpi_uint *) p; -} - -/* - * Set an MPI to static value 1 - */ -static inline void ecp_mpi_set1( mbedtls_mpi *X ) -{ - static mbedtls_mpi_uint one[] = { 1 }; - X->s = 1; - X->n = 1; - X->p = one; -} - -/* - * Make group available from embedded constants - */ -static int ecp_group_load( mbedtls_ecp_group *grp, - const mbedtls_mpi_uint *p, size_t plen, - const mbedtls_mpi_uint *a, size_t alen, - const mbedtls_mpi_uint *b, size_t blen, - const mbedtls_mpi_uint *gx, size_t gxlen, - const mbedtls_mpi_uint *gy, size_t gylen, - const mbedtls_mpi_uint *n, size_t nlen) -{ - ecp_mpi_load( &grp->P, p, plen ); - if( a != NULL ) - ecp_mpi_load( &grp->A, a, alen ); - ecp_mpi_load( &grp->B, b, blen ); - ecp_mpi_load( &grp->N, n, nlen ); - - ecp_mpi_load( &grp->G.X, gx, gxlen ); - ecp_mpi_load( &grp->G.Y, gy, gylen ); - ecp_mpi_set1( &grp->G.Z ); - - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - grp->nbits = mbedtls_mpi_bitlen( &grp->N ); - - grp->h = 1; - - return( 0 ); -} - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* Forward declarations */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static int ecp_mod_p192( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static int ecp_mod_p224( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static int ecp_mod_p256( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static int ecp_mod_p384( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static int ecp_mod_p521( mbedtls_mpi * ); -#endif - -#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; -#else -#define NIST_MODP( P ) -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -/* Additional forward declarations */ -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -static int ecp_mod_p255( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -static int ecp_mod_p448( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static int ecp_mod_p192k1( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static int ecp_mod_p224k1( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static int ecp_mod_p256k1( mbedtls_mpi * ); -#endif - -#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ - G ## _p, sizeof( G ## _p ), \ - G ## _a, sizeof( G ## _a ), \ - G ## _b, sizeof( G ## _b ), \ - G ## _gx, sizeof( G ## _gx ), \ - G ## _gy, sizeof( G ## _gy ), \ - G ## _n, sizeof( G ## _n ) ) - -#define LOAD_GROUP( G ) ecp_group_load( grp, \ - G ## _p, sizeof( G ## _p ), \ - NULL, 0, \ - G ## _b, sizeof( G ## _b ), \ - G ## _gx, sizeof( G ## _gx ), \ - G ## _gy, sizeof( G ## _gy ), \ - G ## _n, sizeof( G ## _n ) ) - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -/* - * Specialized function for creating the Curve25519 group - */ -static int ecp_use_curve25519( mbedtls_ecp_group *grp ) -{ - int ret; - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) ); - - /* P = 2^255 - 19 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) ); - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - - /* N = 2^252 + 27742317777372353535851937790883648493 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->N, 16, - "14DEF9DEA2F79CD65812631A5CF5D3ED" ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) ); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); - mbedtls_mpi_free( &grp->G.Y ); - - /* Actually, the required msb for private keys */ - grp->nbits = 254; - -cleanup: - if( ret != 0 ) - mbedtls_ecp_group_free( grp ); - - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -/* - * Specialized function for creating the Curve448 group - */ -static int ecp_use_curve448( mbedtls_ecp_group *grp ) -{ - mbedtls_mpi Ns; - int ret; - - mbedtls_mpi_init( &Ns ); - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "98AA" ) ); - - /* P = 2^448 - 2^224 - 1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) ); - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); - mbedtls_mpi_free( &grp->G.Y ); - - /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &Ns, 16, - "8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D" ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) ); - - /* Actually, the required msb for private keys */ - grp->nbits = 447; - -cleanup: - mbedtls_mpi_free( &Ns ); - if( ret != 0 ) - mbedtls_ecp_group_free( grp ); - - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -/* - * Set a group using well-known domain parameters - */ -int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) -{ - ECP_VALIDATE_RET( grp != NULL ); - mbedtls_ecp_group_free( grp ); - - grp->id = id; - - switch( id ) - { -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - case MBEDTLS_ECP_DP_SECP192R1: - NIST_MODP( p192 ); - return( LOAD_GROUP( secp192r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - case MBEDTLS_ECP_DP_SECP224R1: - NIST_MODP( p224 ); - return( LOAD_GROUP( secp224r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - case MBEDTLS_ECP_DP_SECP256R1: - NIST_MODP( p256 ); - return( LOAD_GROUP( secp256r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - case MBEDTLS_ECP_DP_SECP384R1: - NIST_MODP( p384 ); - return( LOAD_GROUP( secp384r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - case MBEDTLS_ECP_DP_SECP521R1: - NIST_MODP( p521 ); - return( LOAD_GROUP( secp521r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - case MBEDTLS_ECP_DP_SECP192K1: - grp->modp = ecp_mod_p192k1; - return( LOAD_GROUP_A( secp192k1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - case MBEDTLS_ECP_DP_SECP224K1: - grp->modp = ecp_mod_p224k1; - return( LOAD_GROUP_A( secp224k1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - case MBEDTLS_ECP_DP_SECP256K1: - grp->modp = ecp_mod_p256k1; - return( LOAD_GROUP_A( secp256k1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - case MBEDTLS_ECP_DP_BP256R1: - return( LOAD_GROUP_A( brainpoolP256r1 ) ); -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - case MBEDTLS_ECP_DP_BP384R1: - return( LOAD_GROUP_A( brainpoolP384r1 ) ); -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - case MBEDTLS_ECP_DP_BP512R1: - return( LOAD_GROUP_A( brainpoolP512r1 ) ); -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - grp->modp = ecp_mod_p255; - return( ecp_use_curve25519( grp ) ); -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - grp->modp = ecp_mod_p448; - return( ecp_use_curve448( grp ) ); -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - - default: - mbedtls_ecp_group_free( grp ); - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - } -} - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* - * Fast reduction modulo the primes used by the NIST curves. - * - * These functions are critical for speed, but not needed for correct - * operations. So, we make the choice to heavily rely on the internals of our - * bignum library, which creates a tight coupling between these functions and - * our MPI implementation. However, the coupling between the ECP module and - * MPI remains loose, since these functions can be deactivated at will. - */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -/* - * Compared to the way things are presented in FIPS 186-3 D.2, - * we proceed in columns, from right (least significant chunk) to left, - * adding chunks to N in place, and keeping a carry for the next chunk. - * This avoids moving things around in memory, and uselessly adding zeros, - * compared to the more straightforward, line-oriented approach. - * - * For this prime we need to handle data in chunks of 64 bits. - * Since this is always a multiple of our basic mbedtls_mpi_uint, we can - * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. - */ - -/* Add 64-bit chunks (dst += src) and update carry */ -static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry ) -{ - unsigned char i; - mbedtls_mpi_uint c = 0; - for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ ) - { - *dst += c; c = ( *dst < c ); - *dst += *src; c += ( *dst < *src ); - } - *carry += c; -} - -/* Add carry to a 64-bit chunk and update carry */ -static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry ) -{ - unsigned char i; - for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ ) - { - *dst += *carry; - *carry = ( *dst < *carry ); - } -} - -#define WIDTH 8 / sizeof( mbedtls_mpi_uint ) -#define A( i ) N->p + (i) * WIDTH -#define ADD( i ) add64( p, A( i ), &c ) -#define NEXT p += WIDTH; carry64( p, &c ) -#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 - -/* - * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) - */ -static int ecp_mod_p192( mbedtls_mpi *N ) -{ - int ret; - mbedtls_mpi_uint c = 0; - mbedtls_mpi_uint *p, *end; - - /* Make sure we have enough blocks so that A(5) is legal */ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) ); - - p = N->p; - end = p + N->n; - - ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 - ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 - ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 - -cleanup: - return( ret ); -} - -#undef WIDTH -#undef A -#undef ADD -#undef NEXT -#undef LAST -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A( i ); - -#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ - -#define MAX32 N->n -#define A( j ) N->p[j] -#define STORE32 N->p[i] = cur; - -#else /* 64-bit */ - -#define MAX32 N->n * 2 -#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \ - (uint32_t)( N->p[(j)/2] ) -#define STORE32 \ - if( i % 2 ) { \ - N->p[i/2] &= 0x00000000FFFFFFFF; \ - N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ - } else { \ - N->p[i/2] &= 0xFFFFFFFF00000000; \ - N->p[i/2] |= (mbedtls_mpi_uint) cur; \ - } - -#endif /* sizeof( mbedtls_mpi_uint ) */ - -/* - * Helpers for addition and subtraction of chunks, with signed carry. - */ -static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *dst += src; - *carry += ( *dst < src ); -} - -static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *carry -= ( *dst < src ); - *dst -= src; -} - -#define ADD( j ) add32( &cur, A( j ), &c ); -#define SUB( j ) sub32( &cur, A( j ), &c ); - -/* - * Helpers for the main 'loop' - * (see fix_negative for the motivation of C) - */ -#define INIT( b ) \ - int ret; \ - signed char c = 0, cc; \ - uint32_t cur; \ - size_t i = 0, bits = (b); \ - mbedtls_mpi C; \ - mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \ - \ - C.s = 1; \ - C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \ - C.p = Cp; \ - memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \ - \ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \ - sizeof( mbedtls_mpi_uint ) ) ); \ - LOAD32; - -#define NEXT \ - STORE32; i++; LOAD32; \ - cc = c; c = 0; \ - if( cc < 0 ) \ - sub32( &cur, -cc, &c ); \ - else \ - add32( &cur, cc, &c ); \ - -#define LAST \ - STORE32; i++; \ - cur = c > 0 ? c : 0; STORE32; \ - cur = 0; while( ++i < MAX32 ) { STORE32; } \ - if( c < 0 ) fix_negative( N, c, &C, bits ); - -/* - * If the result is negative, we get it in the form - * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' - */ -static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits ) -{ - int ret; - - /* C = - c * 2^(bits + 32) */ -#if !defined(MBEDTLS_HAVE_INT64) - ((void) bits); -#else - if( bits == 224 ) - C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32; - else -#endif - C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c; - - /* N = - ( C - N ) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) ); - N->s = -1; - -cleanup: - - return( ret ); -} - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224( mbedtls_mpi *N ) -{ - INIT( 224 ); - - SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 - SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 - SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 - SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 - SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 - SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 - SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -/* - * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) - */ -static int ecp_mod_p256( mbedtls_mpi *N ) -{ - INIT( 256 ); - - ADD( 8 ); ADD( 9 ); - SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 - - ADD( 9 ); ADD( 10 ); - SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 - - ADD( 10 ); ADD( 11 ); - SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 - - ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); - SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 - - ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); - SUB( 9 ); SUB( 10 ); NEXT; // A4 - - ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); - SUB( 10 ); SUB( 11 ); NEXT; // A5 - - ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); - SUB( 8 ); SUB( 9 ); NEXT; // A6 - - ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); - SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) - */ -static int ecp_mod_p384( mbedtls_mpi *N ) -{ - INIT( 384 ); - - ADD( 12 ); ADD( 21 ); ADD( 20 ); - SUB( 23 ); NEXT; // A0 - - ADD( 13 ); ADD( 22 ); ADD( 23 ); - SUB( 12 ); SUB( 20 ); NEXT; // A2 - - ADD( 14 ); ADD( 23 ); - SUB( 13 ); SUB( 21 ); NEXT; // A2 - - ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); - SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 - - ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); - SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 - - ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); - SUB( 16 ); NEXT; // A5 - - ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); - SUB( 17 ); NEXT; // A6 - - ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); - SUB( 18 ); NEXT; // A7 - - ADD( 20 ); ADD( 17 ); ADD( 16 ); - SUB( 19 ); NEXT; // A8 - - ADD( 21 ); ADD( 18 ); ADD( 17 ); - SUB( 20 ); NEXT; // A9 - - ADD( 22 ); ADD( 19 ); ADD( 18 ); - SUB( 21 ); NEXT; // A10 - - ADD( 23 ); ADD( 20 ); ADD( 19 ); - SUB( 22 ); LAST; // A11 - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#undef A -#undef LOAD32 -#undef STORE32 -#undef MAX32 -#undef INIT -#undef NEXT -#undef LAST - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || - MBEDTLS_ECP_DP_SECP256R1_ENABLED || - MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -/* - * Here we have an actual Mersenne prime, so things are more straightforward. - * However, chunks are aligned on a 'weird' boundary (521 bits). - */ - -/* Size of p521 in terms of mbedtls_mpi_uint */ -#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) - -/* Bits to keep in the most significant mbedtls_mpi_uint */ -#define P521_MASK 0x01FF - -/* - * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) - * Write N as A1 + 2^521 A0, return A0 + A1 - */ -static int ecp_mod_p521( mbedtls_mpi *N ) -{ - int ret; - size_t i; - mbedtls_mpi M; - mbedtls_mpi_uint Mp[P521_WIDTH + 1]; - /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: - * we need to hold bits 513 to 1056, which is 34 limbs, that is - * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ - - if( N->n < P521_WIDTH ) - return( 0 ); - - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P521_WIDTH - 1 ); - if( M.n > P521_WIDTH + 1 ) - M.n = P521_WIDTH + 1; - M.p = Mp; - memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); - - /* N = A0 */ - N->p[P521_WIDTH - 1] &= P521_MASK; - for( i = P521_WIDTH; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - -cleanup: - return( ret ); -} - -#undef P521_WIDTH -#undef P521_MASK -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - -/* Size of p255 in terms of mbedtls_mpi_uint */ -#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) - -/* - * Fast quasi-reduction modulo p255 = 2^255 - 19 - * Write N as A0 + 2^255 A1, return A0 + 19 * A1 - */ -static int ecp_mod_p255( mbedtls_mpi *N ) -{ - int ret; - size_t i; - mbedtls_mpi M; - mbedtls_mpi_uint Mp[P255_WIDTH + 2]; - - if( N->n < P255_WIDTH ) - return( 0 ); - - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P255_WIDTH - 1 ); - if( M.n > P255_WIDTH + 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - M.p = Mp; - memset( Mp, 0, sizeof Mp ); - memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); - M.n++; /* Make room for multiplication by 19 */ - - /* N = A0 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) ); - for( i = P255_WIDTH; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + 19 * A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - -/* Size of p448 in terms of mbedtls_mpi_uint */ -#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) ) - -/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */ -#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) ) -#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) ) -#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) ) -#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 ) - -/* - * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 - * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return - * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference - * implementation of Curve448, which uses its own special 56-bit limbs rather - * than a generic bignum library. We could squeeze some extra speed out on - * 32-bit machines by splitting N up into 32-bit limbs and doing the - * arithmetic using the limbs directly as we do for the NIST primes above, - * but for 64-bit targets it should use half the number of operations if we do - * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds. - */ -static int ecp_mod_p448( mbedtls_mpi *N ) -{ - int ret; - size_t i; - mbedtls_mpi M, Q; - mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH]; - - if( N->n <= P448_WIDTH ) - return( 0 ); - - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P448_WIDTH ); - if( M.n > P448_WIDTH ) - /* Shouldn't be called with N larger than 2^896! */ - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - M.p = Mp; - memset( Mp, 0, sizeof( Mp ) ); - memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) ); - - /* N = A0 */ - for( i = P448_WIDTH; i < N->n; i++ ) - N->p[i] = 0; - - /* N += A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) ); - - /* Q = B1, N += B1 */ - Q = M; - Q.p = Qp; - memcpy( Qp, Mp, sizeof( Qp ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) ); - - /* M = (B0 + B1) * 2^224, N += M */ - if( sizeof( mbedtls_mpi_uint ) > 4 ) - Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS ); - for( i = P224_WIDTH_MAX; i < M.n; ++i ) - Mp[i] = 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) ); - M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */ - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* - * Fast quasi-reduction modulo P = 2^s - R, - * with R about 33 bits, used by the Koblitz curves. - * - * Write N as A0 + 2^224 A1, return A0 + R * A1. - * Actually do two passes, since R is big. - */ -#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P -#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R -static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs, - size_t adjust, size_t shift, mbedtls_mpi_uint mask ) -{ - int ret; - size_t i; - mbedtls_mpi M, R; - mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; - - if( N->n < p_limbs ) - return( 0 ); - - /* Init R */ - R.s = 1; - R.p = Rp; - R.n = P_KOBLITZ_R; - - /* Common setup for M */ - M.s = 1; - M.p = Mp; - - /* M = A1 */ - M.n = N->n - ( p_limbs - adjust ); - if( M.n > p_limbs + adjust ) - M.n = p_limbs + adjust; - memset( Mp, 0, sizeof Mp ); - memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); - if( shift != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); - M.n += R.n; /* Make room for multiplication by R */ - - /* N = A0 */ - if( mask != 0 ) - N->p[p_limbs - 1] &= mask; - for( i = p_limbs; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + R * A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - - /* Second pass */ - - /* M = A1 */ - M.n = N->n - ( p_limbs - adjust ); - if( M.n > p_limbs + adjust ) - M.n = p_limbs + adjust; - memset( Mp, 0, sizeof Mp ); - memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); - if( shift != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); - M.n += R.n; /* Make room for multiplication by R */ - - /* N = A0 */ - if( mask != 0 ) - N->p[p_limbs - 1] &= mask; - for( i = p_limbs; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + R * A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || - MBEDTLS_ECP_DP_SECP224K1_ENABLED) || - MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -/* - * Fast quasi-reduction modulo p192k1 = 2^192 - R, - * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 - */ -static int ecp_mod_p192k1( mbedtls_mpi *N ) -{ - static mbedtls_mpi_uint Rp[] = { - BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; - - return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); -} -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -/* - * Fast quasi-reduction modulo p224k1 = 2^224 - R, - * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 - */ -static int ecp_mod_p224k1( mbedtls_mpi *N ) -{ - static mbedtls_mpi_uint Rp[] = { - BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; - -#if defined(MBEDTLS_HAVE_INT64) - return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); -#else - return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); -#endif -} - -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* - * Fast quasi-reduction modulo p256k1 = 2^256 - R, - * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 - */ -static int ecp_mod_p256k1( mbedtls_mpi *N ) -{ - static mbedtls_mpi_uint Rp[] = { - BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; - return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); -} -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#endif /* !MBEDTLS_ECP_ALT */ - -#endif /* MBEDTLS_ECP_C */ diff --git a/library/entropy.c b/library/entropy.c deleted file mode 100644 index f8db1a5503..0000000000 --- a/library/entropy.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Entropy accumulator implementation - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ENTROPY_C) - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) -#warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! " -#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES " -#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE " -#endif - -#include "mbedtls/entropy.h" -#include "mbedtls/entropy_poll.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#include "mbedtls/platform.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if defined(MBEDTLS_HAVEGE_C) -#include "mbedtls/havege.h" -#endif - -#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ - -void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) -{ - ctx->source_count = 0; - memset( ctx->source, 0, sizeof( ctx->source ) ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif - - ctx->accumulator_started = 0; -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - mbedtls_sha512_init( &ctx->accumulator ); -#else - mbedtls_sha256_init( &ctx->accumulator ); -#endif -#if defined(MBEDTLS_HAVEGE_C) - mbedtls_havege_init( &ctx->havege_data ); -#endif - - /* Reminder: Update ENTROPY_HAVE_STRONG in the test files - * when adding more strong entropy sources here. */ - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) - mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, - 1, MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif - -#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) - mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, - MBEDTLS_ENTROPY_MIN_PLATFORM, - MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif -#if defined(MBEDTLS_TIMING_C) - mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, - MBEDTLS_ENTROPY_MIN_HARDCLOCK, - MBEDTLS_ENTROPY_SOURCE_WEAK ); -#endif -#if defined(MBEDTLS_HAVEGE_C) - mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data, - MBEDTLS_ENTROPY_MIN_HAVEGE, - MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, - MBEDTLS_ENTROPY_MIN_HARDWARE, - MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) - mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, - MBEDTLS_ENTROPY_BLOCK_SIZE, - MBEDTLS_ENTROPY_SOURCE_STRONG ); - ctx->initial_entropy_run = 0; -#endif -#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ -} - -void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) -{ -#if defined(MBEDTLS_HAVEGE_C) - mbedtls_havege_free( &ctx->havege_data ); -#endif -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - mbedtls_sha512_free( &ctx->accumulator ); -#else - mbedtls_sha256_free( &ctx->accumulator ); -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) - ctx->initial_entropy_run = 0; -#endif - ctx->source_count = 0; - mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) ); - ctx->accumulator_started = 0; -} - -int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, - mbedtls_entropy_f_source_ptr f_source, void *p_source, - size_t threshold, int strong ) -{ - int idx, ret = 0; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - idx = ctx->source_count; - if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES ) - { - ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES; - goto exit; - } - - ctx->source[idx].f_source = f_source; - ctx->source[idx].p_source = p_source; - ctx->source[idx].threshold = threshold; - ctx->source[idx].strong = strong; - - ctx->source_count++; - -exit: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Entropy accumulator update - */ -static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id, - const unsigned char *data, size_t len ) -{ - unsigned char header[2]; - unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; - size_t use_len = len; - const unsigned char *p = data; - int ret = 0; - - if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE ) - { -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 ) - goto cleanup; -#else - if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 ) - goto cleanup; -#endif - p = tmp; - use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; - } - - header[0] = source_id; - header[1] = use_len & 0xFF; - - /* - * Start the accumulator if this has not already happened. Note that - * it is sufficient to start the accumulator here only because all calls to - * gather entropy eventually execute this code. - */ -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - if( ctx->accumulator_started == 0 && - ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto cleanup; - else - ctx->accumulator_started = 1; - if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 ) - goto cleanup; - ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len ); -#else - if( ctx->accumulator_started == 0 && - ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto cleanup; - else - ctx->accumulator_started = 1; - if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 ) - goto cleanup; - ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len ); -#endif - -cleanup: - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - - return( ret ); -} - -int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, - const unsigned char *data, size_t len ) -{ - int ret; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Run through the different sources to add entropy to our accumulator - */ -static int entropy_gather_internal( mbedtls_entropy_context *ctx ) -{ - int ret, i, have_one_strong = 0; - unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; - size_t olen; - - if( ctx->source_count == 0 ) - return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED ); - - /* - * Run through our entropy sources - */ - for( i = 0; i < ctx->source_count; i++ ) - { - if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) - have_one_strong = 1; - - olen = 0; - if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, - buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 ) - { - goto cleanup; - } - - /* - * Add if we actually gathered something - */ - if( olen > 0 ) - { - if( ( ret = entropy_update( ctx, (unsigned char) i, - buf, olen ) ) != 0 ) - return( ret ); - ctx->source[i].size += olen; - } - } - - if( have_one_strong == 0 ) - ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} - -/* - * Thread-safe wrapper for entropy_gather_internal() - */ -int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) -{ - int ret; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = entropy_gather_internal( ctx ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) -{ - int ret, count = 0, i, done; - mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - -#if defined(MBEDTLS_ENTROPY_NV_SEED) - /* Update the NV entropy seed before generating any entropy for outside - * use. - */ - if( ctx->initial_entropy_run == 0 ) - { - ctx->initial_entropy_run = 1; - if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) - return( ret ); - } -#endif - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - /* - * Always gather extra entropy before a call - */ - do - { - if( count++ > ENTROPY_MAX_LOOP ) - { - ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - goto exit; - } - - if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) - goto exit; - - done = 1; - for( i = 0; i < ctx->source_count; i++ ) - if( ctx->source[i].size < ctx->source[i].threshold ) - done = 0; - } - while( ! done ); - - memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); - -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - /* - * Note that at this stage it is assumed that the accumulator was started - * in a previous call to entropy_update(). If this is not guaranteed, the - * code below will fail. - */ - if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 ) - goto exit; - - /* - * Reset accumulator and counters and recycle existing entropy - */ - mbedtls_sha512_free( &ctx->accumulator ); - mbedtls_sha512_init( &ctx->accumulator ); - if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf, - MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - goto exit; - - /* - * Perform second SHA-512 on entropy - */ - if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, - buf, 0 ) ) != 0 ) - goto exit; -#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ - if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 ) - goto exit; - - /* - * Reset accumulator and counters and recycle existing entropy - */ - mbedtls_sha256_free( &ctx->accumulator ); - mbedtls_sha256_init( &ctx->accumulator ); - if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf, - MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - goto exit; - - /* - * Perform second SHA-256 on entropy - */ - if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, - buf, 0 ) ) != 0 ) - goto exit; -#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ - - for( i = 0; i < ctx->source_count; i++ ) - ctx->source[i].size = 0; - - memcpy( output, buf, len ); - - ret = 0; - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) -{ - int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - /* Read new seed and write it to NV */ - if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - return( ret ); - - if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) - return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); - - /* Manually update the remaining stream with a separator value to diverge */ - memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); - ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); - - return( ret ); -} -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if defined(MBEDTLS_FS_IO) -int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) -{ - int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - FILE *f; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - if( ( f = fopen( path, "wb" ) ) == NULL ) - return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); - - if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - goto exit; - - if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE ) - { - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - goto exit; - } - - ret = 0; - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - fclose( f ); - return( ret ); -} - -int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ) -{ - int ret = 0; - FILE *f; - size_t n; - unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); - - fseek( f, 0, SEEK_END ); - n = (size_t) ftell( f ); - fseek( f, 0, SEEK_SET ); - - if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) - n = MBEDTLS_ENTROPY_MAX_SEED_SIZE; - - if( fread( buf, 1, n, f ) != n ) - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - else - ret = mbedtls_entropy_update_manual( ctx, buf, n ); - - fclose( f ); - - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - if( ret != 0 ) - return( ret ); - - return( mbedtls_entropy_write_seed_file( ctx, path ) ); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) -#if !defined(MBEDTLS_TEST_NULL_ENTROPY) -/* - * Dummy source function - */ -static int entropy_dummy_source( void *data, unsigned char *output, - size_t len, size_t *olen ) -{ - ((void) data); - - memset( output, 0x2a, len ); - *olen = len; - - return( 0 ); -} -#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - -static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len ) -{ - int ret = 0; - size_t entropy_len = 0; - size_t olen = 0; - size_t attempts = buf_len; - - while( attempts > 0 && entropy_len < buf_len ) - { - if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len, - buf_len - entropy_len, &olen ) ) != 0 ) - return( ret ); - - entropy_len += olen; - attempts--; - } - - if( entropy_len < buf_len ) - { - ret = 1; - } - - return( ret ); -} - - -static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf, - size_t buf_len ) -{ - unsigned char set= 0xFF; - unsigned char unset = 0x00; - size_t i; - - for( i = 0; i < buf_len; i++ ) - { - set &= buf[i]; - unset |= buf[i]; - } - - return( set == 0xFF || unset == 0x00 ); -} - -/* - * A test to ensure hat the entropy sources are functioning correctly - * and there is no obvious failure. The test performs the following checks: - * - The entropy source is not providing only 0s (all bits unset) or 1s (all - * bits set). - * - The entropy source is not providing values in a pattern. Because the - * hardware could be providing data in an arbitrary length, this check polls - * the hardware entropy source twice and compares the result to ensure they - * are not equal. - * - The error code returned by the entropy source is not an error. - */ -int mbedtls_entropy_source_self_test( int verbose ) -{ - int ret = 0; - unsigned char buf0[2 * sizeof( unsigned long long int )]; - unsigned char buf1[2 * sizeof( unsigned long long int )]; - - if( verbose != 0 ) - mbedtls_printf( " ENTROPY_BIAS test: " ); - - memset( buf0, 0x00, sizeof( buf0 ) ); - memset( buf1, 0x00, sizeof( buf1 ) ); - - if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 ) - goto cleanup; - - /* Make sure that the returned values are not all 0 or 1 */ - if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 ) - goto cleanup; - - /* Make sure that the entropy source is not returning values in a - * pattern */ - ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0; - -cleanup: - if( verbose != 0 ) - { - if( ret != 0 ) - mbedtls_printf( "failed\n" ); - else - mbedtls_printf( "passed\n" ); - - mbedtls_printf( "\n" ); - } - - return( ret != 0 ); -} - -#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ - -/* - * The actual entropy quality is hard to test, but we can at least - * test that the functions don't cause errors and write the correct - * amount of data to buffers. - */ -int mbedtls_entropy_self_test( int verbose ) -{ - int ret = 1; -#if !defined(MBEDTLS_TEST_NULL_ENTROPY) - mbedtls_entropy_context ctx; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; - unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; - size_t i, j; -#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ - - if( verbose != 0 ) - mbedtls_printf( " ENTROPY test: " ); - -#if !defined(MBEDTLS_TEST_NULL_ENTROPY) - mbedtls_entropy_init( &ctx ); - - /* First do a gather to make sure we have default sources */ - if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 ) - goto cleanup; - - ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16, - MBEDTLS_ENTROPY_SOURCE_WEAK ); - if( ret != 0 ) - goto cleanup; - - if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 ) - goto cleanup; - - /* - * To test that mbedtls_entropy_func writes correct number of bytes: - * - use the whole buffer and rely on ASan to detect overruns - * - collect entropy 8 times and OR the result in an accumulator: - * any byte should then be 0 with probably 2^(-64), so requiring - * each of the 32 or 64 bytes to be non-zero has a false failure rate - * of at most 2^(-58) which is acceptable. - */ - for( i = 0; i < 8; i++ ) - { - if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 ) - goto cleanup; - - for( j = 0; j < sizeof( buf ); j++ ) - acc[j] |= buf[j]; - } - - for( j = 0; j < sizeof( buf ); j++ ) - { - if( acc[j] == 0 ) - { - ret = 1; - goto cleanup; - } - } - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 ) - goto cleanup; -#endif - -cleanup: - mbedtls_entropy_free( &ctx ); -#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ - - if( verbose != 0 ) - { - if( ret != 0 ) - mbedtls_printf( "failed\n" ); - else - mbedtls_printf( "passed\n" ); - - mbedtls_printf( "\n" ); - } - - return( ret != 0 ); -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ENTROPY_C */ diff --git a/library/entropy_poll.c b/library/entropy_poll.c deleted file mode 100644 index 4556f88a55..0000000000 --- a/library/entropy_poll.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Platform-specific and custom entropy polling functions - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if defined(__linux__) -/* Ensure that syscall() is available even when compiling with -std=c99 */ -#define _GNU_SOURCE -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#if defined(MBEDTLS_ENTROPY_C) - -#include "mbedtls/entropy.h" -#include "mbedtls/entropy_poll.h" - -#if defined(MBEDTLS_TIMING_C) -#include "mbedtls/timing.h" -#endif -#if defined(MBEDTLS_HAVEGE_C) -#include "mbedtls/havege.h" -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#include "mbedtls/platform.h" -#endif - -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) - -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) -#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -#if !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0400 -#endif -#include -#include - -int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, - size_t *olen ) -{ - HCRYPTPROV provider; - ((void) data); - *olen = 0; - - if( CryptAcquireContext( &provider, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) - { - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - } - - if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) - { - CryptReleaseContext( provider, 0 ); - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - } - - CryptReleaseContext( provider, 0 ); - *olen = len; - - return( 0 ); -} -#else /* _WIN32 && !EFIX64 && !EFI32 */ - -/* - * Test for Linux getrandom() support. - * Since there is no wrapper in the libc yet, use the generic syscall wrapper - * available in GNU libc and compatible libc's (eg uClibc). - */ -#if defined(__linux__) && defined(__GLIBC__) -#include -#include -#if defined(SYS_getrandom) -#define HAVE_GETRANDOM -#include - -static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) -{ - /* MemSan cannot understand that the syscall writes to the buffer */ -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) - memset( buf, 0, buflen ); -#endif -#endif - return( syscall( SYS_getrandom, buf, buflen, flags ) ); -} -#endif /* SYS_getrandom */ -#endif /* __linux__ */ - -#include - -int mbedtls_platform_entropy_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - FILE *file; - size_t read_len; - int ret; - ((void) data); - -#if defined(HAVE_GETRANDOM) - ret = getrandom_wrapper( output, len, 0 ); - if( ret >= 0 ) - { - *olen = ret; - return( 0 ); - } - else if( errno != ENOSYS ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - /* Fall through if the system call isn't known. */ -#else - ((void) ret); -#endif /* HAVE_GETRANDOM */ - - *olen = 0; - - file = fopen( "/dev/urandom", "rb" ); - if( file == NULL ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - - read_len = fread( output, 1, len, file ); - if( read_len != len ) - { - fclose( file ); - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - } - - fclose( file ); - *olen = len; - - return( 0 ); -} -#endif /* _WIN32 && !EFIX64 && !EFI32 */ -#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) -int mbedtls_null_entropy_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - ((void) data); - ((void) output); - *olen = 0; - - if( len < sizeof(unsigned char) ) - return( 0 ); - - *olen = sizeof(unsigned char); - - return( 0 ); -} -#endif - -#if defined(MBEDTLS_TIMING_C) -int mbedtls_hardclock_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - unsigned long timer = mbedtls_timing_hardclock(); - ((void) data); - *olen = 0; - - if( len < sizeof(unsigned long) ) - return( 0 ); - - memcpy( output, &timer, sizeof(unsigned long) ); - *olen = sizeof(unsigned long); - - return( 0 ); -} -#endif /* MBEDTLS_TIMING_C */ - -#if defined(MBEDTLS_HAVEGE_C) -int mbedtls_havege_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - mbedtls_havege_state *hs = (mbedtls_havege_state *) data; - *olen = 0; - - if( mbedtls_havege_random( hs, output, len ) != 0 ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - - *olen = len; - - return( 0 ); -} -#endif /* MBEDTLS_HAVEGE_C */ - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -int mbedtls_nv_seed_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; - ((void) data); - - memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); - - if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - - if( len < use_len ) - use_len = len; - - memcpy( output, buf, use_len ); - *olen = use_len; - - return( 0 ); -} -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#endif /* MBEDTLS_ENTROPY_C */ diff --git a/library/gcm.c b/library/gcm.c deleted file mode 100644 index 5121a7ac7e..0000000000 --- a/library/gcm.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * NIST SP800-38D compliant GCM implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf - * - * See also: - * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf - * - * We use the algorithm described as Shoup's method with 4-bit tables in - * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_GCM_C) - -#include "mbedtls/gcm.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_AESNI_C) -#include "mbedtls/aesni.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#include "mbedtls/platform.h" -#if !defined(MBEDTLS_PLATFORM_C) -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#if !defined(MBEDTLS_GCM_ALT) - -/* Parameter validation macros */ -#define GCM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT ) -#define GCM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * Initialize a context - */ -void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) -{ - GCM_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_gcm_context ) ); -} - -/* - * Precompute small multiples of H, that is set - * HH[i] || HL[i] = H times i, - * where i is seen as a field element as in [MGV], ie high-order bits - * correspond to low powers of P. The result is stored in the same way, that - * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL - * corresponds to P^127. - */ -static int gcm_gen_table( mbedtls_gcm_context *ctx ) -{ - int ret, i, j; - uint64_t hi, lo; - uint64_t vl, vh; - unsigned char h[16]; - size_t olen = 0; - - memset( h, 0, 16 ); - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) - return( ret ); - - /* pack h as two 64-bits ints, big-endian */ - GET_UINT32_BE( hi, h, 0 ); - GET_UINT32_BE( lo, h, 4 ); - vh = (uint64_t) hi << 32 | lo; - - GET_UINT32_BE( hi, h, 8 ); - GET_UINT32_BE( lo, h, 12 ); - vl = (uint64_t) hi << 32 | lo; - - /* 8 = 1000 corresponds to 1 in GF(2^128) */ - ctx->HL[8] = vl; - ctx->HH[8] = vh; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - /* With CLMUL support, we need only h, not the rest of the table */ - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) - return( 0 ); -#endif - - /* 0 corresponds to 0 in GF(2^128) */ - ctx->HH[0] = 0; - ctx->HL[0] = 0; - - for( i = 4; i > 0; i >>= 1 ) - { - uint32_t T = ( vl & 1 ) * 0xe1000000U; - vl = ( vh << 63 ) | ( vl >> 1 ); - vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); - - ctx->HL[i] = vl; - ctx->HH[i] = vh; - } - - for( i = 2; i <= 8; i *= 2 ) - { - uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; - vh = *HiH; - vl = *HiL; - for( j = 1; j < i; j++ ) - { - HiH[j] = vh ^ ctx->HH[j]; - HiL[j] = vl ^ ctx->HL[j]; - } - } - - return( 0 ); -} - -int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( key != NULL ); - GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 ); - - cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, - MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = gcm_gen_table( ctx ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Shoup's method for multiplication use this table with - * last4[x] = x times P^128 - * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] - */ -static const uint64_t last4[16] = -{ - 0x0000, 0x1c20, 0x3840, 0x2460, - 0x7080, 0x6ca0, 0x48c0, 0x54e0, - 0xe100, 0xfd20, 0xd940, 0xc560, - 0x9180, 0x8da0, 0xa9c0, 0xb5e0 -}; - -/* - * Sets output to x times H using the precomputed tables. - * x and output are seen as elements of GF(2^128) as in [MGV]. - */ -static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], - unsigned char output[16] ) -{ - int i = 0; - unsigned char lo, hi, rem; - uint64_t zh, zl; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { - unsigned char h[16]; - - PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); - PUT_UINT32_BE( ctx->HH[8], h, 4 ); - PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); - PUT_UINT32_BE( ctx->HL[8], h, 12 ); - - mbedtls_aesni_gcm_mult( output, x, h ); - return; - } -#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */ - - lo = x[15] & 0xf; - - zh = ctx->HH[lo]; - zl = ctx->HL[lo]; - - for( i = 15; i >= 0; i-- ) - { - lo = x[i] & 0xf; - hi = x[i] >> 4; - - if( i != 15 ) - { - rem = (unsigned char) zl & 0xf; - zl = ( zh << 60 ) | ( zl >> 4 ); - zh = ( zh >> 4 ); - zh ^= (uint64_t) last4[rem] << 48; - zh ^= ctx->HH[lo]; - zl ^= ctx->HL[lo]; - - } - - rem = (unsigned char) zl & 0xf; - zl = ( zh << 60 ) | ( zl >> 4 ); - zh = ( zh >> 4 ); - zh ^= (uint64_t) last4[rem] << 48; - zh ^= ctx->HH[hi]; - zl ^= ctx->HL[hi]; - } - - PUT_UINT32_BE( zh >> 32, output, 0 ); - PUT_UINT32_BE( zh, output, 4 ); - PUT_UINT32_BE( zl >> 32, output, 8 ); - PUT_UINT32_BE( zl, output, 12 ); -} - -int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len ) -{ - int ret; - unsigned char work_buf[16]; - size_t i; - const unsigned char *p; - size_t use_len, olen = 0; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - - /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ - /* IV is not allowed to be zero length */ - if( iv_len == 0 || - ( (uint64_t) iv_len ) >> 61 != 0 || - ( (uint64_t) add_len ) >> 61 != 0 ) - { - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - } - - memset( ctx->y, 0x00, sizeof(ctx->y) ); - memset( ctx->buf, 0x00, sizeof(ctx->buf) ); - - ctx->mode = mode; - ctx->len = 0; - ctx->add_len = 0; - - if( iv_len == 12 ) - { - memcpy( ctx->y, iv, iv_len ); - ctx->y[15] = 1; - } - else - { - memset( work_buf, 0x00, 16 ); - PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); - - p = iv; - while( iv_len > 0 ) - { - use_len = ( iv_len < 16 ) ? iv_len : 16; - - for( i = 0; i < use_len; i++ ) - ctx->y[i] ^= p[i]; - - gcm_mult( ctx, ctx->y, ctx->y ); - - iv_len -= use_len; - p += use_len; - } - - for( i = 0; i < 16; i++ ) - ctx->y[i] ^= work_buf[i]; - - gcm_mult( ctx, ctx->y, ctx->y ); - } - - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, - ctx->base_ectr, &olen ) ) != 0 ) - { - return( ret ); - } - - ctx->add_len = add_len; - p = add; - while( add_len > 0 ) - { - use_len = ( add_len < 16 ) ? add_len : 16; - - for( i = 0; i < use_len; i++ ) - ctx->buf[i] ^= p[i]; - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - add_len -= use_len; - p += use_len; - } - - return( 0 ); -} - -int mbedtls_gcm_update( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char ectr[16]; - size_t i; - const unsigned char *p; - unsigned char *out_p = output; - size_t use_len, olen = 0; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - - if( output > input && (size_t) ( output - input ) < length ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes - * Also check for possible overflow */ - if( ctx->len + length < ctx->len || - (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) - { - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - } - - ctx->len += length; - - p = input; - while( length > 0 ) - { - use_len = ( length < 16 ) ? length : 16; - - for( i = 16; i > 12; i-- ) - if( ++ctx->y[i - 1] != 0 ) - break; - - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, - &olen ) ) != 0 ) - { - return( ret ); - } - - for( i = 0; i < use_len; i++ ) - { - if( ctx->mode == MBEDTLS_GCM_DECRYPT ) - ctx->buf[i] ^= p[i]; - out_p[i] = ectr[i] ^ p[i]; - if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) - ctx->buf[i] ^= out_p[i]; - } - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - length -= use_len; - p += use_len; - out_p += use_len; - } - - return( 0 ); -} - -int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, - unsigned char *tag, - size_t tag_len ) -{ - unsigned char work_buf[16]; - size_t i; - uint64_t orig_len; - uint64_t orig_add_len; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - - orig_len = ctx->len * 8; - orig_add_len = ctx->add_len * 8; - - if( tag_len > 16 || tag_len < 4 ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - memcpy( tag, ctx->base_ectr, tag_len ); - - if( orig_len || orig_add_len ) - { - memset( work_buf, 0x00, 16 ); - - PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); - PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); - PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); - PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); - - for( i = 0; i < 16; i++ ) - ctx->buf[i] ^= work_buf[i]; - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - for( i = 0; i < tag_len; i++ ) - tag[i] ^= ctx->buf[i]; - } - - return( 0 ); -} - -int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag ) -{ - int ret; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - - if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char check_tag[16]; - size_t i; - int diff; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - - if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, tag_len, check_tag ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_platform_zeroize( output, length ); - return( MBEDTLS_ERR_GCM_AUTH_FAILED ); - } - - return( 0 ); -} - -void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) -{ - if( ctx == NULL ) - return; - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); -} - -#endif /* !MBEDTLS_GCM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/* - * AES-GCM test vectors from: - * - * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip - */ -#define MAX_TESTS 6 - -static const int key_index_test_data[MAX_TESTS] = - { 0, 0, 1, 1, 1, 1 }; - -static const unsigned char key_test_data[MAX_TESTS][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, -}; - -static const size_t iv_len_test_data[MAX_TESTS] = - { 12, 12, 12, 12, 8, 60 }; - -static const int iv_index_test_data[MAX_TESTS] = - { 0, 0, 1, 1, 1, 2 }; - -static const unsigned char iv_test_data[MAX_TESTS][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, - 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, - 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, - 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, - 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, - 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, - 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, - 0xa6, 0x37, 0xb3, 0x9b }, -}; - -static const size_t add_len_test_data[MAX_TESTS] = - { 0, 0, 0, 20, 20, 20 }; - -static const int add_index_test_data[MAX_TESTS] = - { 0, 0, 0, 1, 1, 1 }; - -static const unsigned char additional_test_data[MAX_TESTS][64] = -{ - { 0x00 }, - { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 }, -}; - -static const size_t pt_len_test_data[MAX_TESTS] = - { 0, 16, 64, 60, 60, 60 }; - -static const int pt_index_test_data[MAX_TESTS] = - { 0, 0, 1, 1, 1, 1 }; - -static const unsigned char pt_test_data[MAX_TESTS][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, -}; - -static const unsigned char ct_test_data[MAX_TESTS * 3][64] = -{ - { 0x00 }, - { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, - 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 }, - { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, - 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, - 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, - 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, - 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, - 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, - 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, - 0xc2, 0x3f, 0x45, 0x98 }, - { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, - 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, - 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, - 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, - 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, - 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, - 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, - 0x4c, 0x34, 0xae, 0xe5 }, - { 0x00 }, - { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, - 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10 }, - { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, - 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, - 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, - 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, - 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, - 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, - 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, - 0xa0, 0xf0, 0x62, 0xf7 }, - { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, - 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, - 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, - 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, - 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, - 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, - 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, - 0xe9, 0xb7, 0x37, 0x3b }, - { 0x00 }, - { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, - 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62 }, - { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, - 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, - 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, - 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, - 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, - 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, - 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, - 0xf4, 0x7c, 0x9b, 0x1f }, - { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, - 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, - 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, - 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, - 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, - 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, - 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, - 0x44, 0xae, 0x7e, 0x3f }, -}; - -static const unsigned char tag_test_data[MAX_TESTS * 3][16] = -{ - { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, - 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, - { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, - 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, - { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, - 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, - { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, - 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, - { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, - 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, - { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, - 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, - { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, - 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, - { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, - 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, - { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, - 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, - { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, - 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, - { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, - 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, - { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, - 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, - { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, - 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, - { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, - 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, - { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, - 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, - { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, - 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, - { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, - 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, - { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, - 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, -}; - -int mbedtls_gcm_self_test( int verbose ) -{ - mbedtls_gcm_context ctx; - unsigned char buf[64]; - unsigned char tag_buf[16]; - int i, j, ret; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - - for( j = 0; j < 3; j++ ) - { - int key_len = 128 + 64 * j; - - for( i = 0; i < MAX_TESTS; i++ ) - { - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d (%s): ", - key_len, i, "enc" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 ) - { - mbedtls_printf( "skipped\n" ); - break; - } - else if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, - pt_len_test_data[i], - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i], - pt_test_data[pt_index_test_data[i]], - buf, 16, tag_buf ); - if( ret != 0 ) - goto exit; - - if ( memcmp( buf, ct_test_data[j * 6 + i], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d (%s): ", - key_len, i, "dec" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, - pt_len_test_data[i], - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i], - ct_test_data[j * 6 + i], buf, 16, tag_buf ); - - if( ret != 0 ) - goto exit; - - if( memcmp( buf, pt_test_data[pt_index_test_data[i]], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", - key_len, i, "enc" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i] ); - if( ret != 0 ) - goto exit; - - if( pt_len_test_data[i] > 32 ) - { - size_t rest_len = pt_len_test_data[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, - pt_test_data[pt_index_test_data[i]], - buf ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_update( &ctx, rest_len, - pt_test_data[pt_index_test_data[i]] + 32, - buf + 32 ); - if( ret != 0 ) - goto exit; - } - else - { - ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], - pt_test_data[pt_index_test_data[i]], - buf ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, ct_test_data[j * 6 + i], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", - key_len, i, "dec" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i] ); - if( ret != 0 ) - goto exit; - - if( pt_len_test_data[i] > 32 ) - { - size_t rest_len = pt_len_test_data[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i], - buf ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_update( &ctx, rest_len, - ct_test_data[j * 6 + i] + 32, - buf + 32 ); - if( ret != 0 ) - goto exit; - } - else - { - ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i], - ct_test_data[j * 6 + i], - buf ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, pt_test_data[pt_index_test_data[i]], - pt_len_test_data[i] ) != 0 || - memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - ret = 0; - -exit: - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - mbedtls_gcm_free( &ctx ); - } - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_GCM_C */ diff --git a/library/havege.c b/library/havege.c deleted file mode 100644 index 54f897c6e7..0000000000 --- a/library/havege.c +++ /dev/null @@ -1,241 +0,0 @@ -/** - * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The HAVEGE RNG was designed by Andre Seznec in 2002. - * - * http://www.irisa.fr/caps/projects/hipsor/publi.php - * - * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HAVEGE_C) - -#include "mbedtls/havege.h" -#include "mbedtls/timing.h" -#include "mbedtls/platform_util.h" - -#include - -/* ------------------------------------------------------------------------ - * On average, one iteration accesses two 8-word blocks in the havege WALK - * table, and generates 16 words in the RES array. - * - * The data read in the WALK table is updated and permuted after each use. - * The result of the hardware clock counter read is used for this update. - * - * 25 conditional tests are present. The conditional tests are grouped in - * two nested groups of 12 conditional tests and 1 test that controls the - * permutation; on average, there should be 6 tests executed and 3 of them - * should be mispredicted. - * ------------------------------------------------------------------------ - */ - -#define SWAP(X,Y) { int *T = (X); (X) = (Y); (Y) = T; } - -#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; -#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; - -#define TST1_LEAVE U1++; } -#define TST2_LEAVE U2++; } - -#define ONE_ITERATION \ - \ - PTEST = PT1 >> 20; \ - \ - TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ - TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ - TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ - \ - TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ - TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ - TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ - \ - PTX = (PT1 >> 18) & 7; \ - PT1 &= 0x1FFF; \ - PT2 &= 0x1FFF; \ - CLK = (int) mbedtls_timing_hardclock(); \ - \ - i = 0; \ - A = &WALK[PT1 ]; RES[i++] ^= *A; \ - B = &WALK[PT2 ]; RES[i++] ^= *B; \ - C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \ - D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \ - \ - IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \ - *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \ - *B = IN ^ U1; \ - *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \ - *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \ - \ - A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \ - B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \ - C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \ - D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \ - \ - if( PTEST & 1 ) SWAP( A, C ); \ - \ - IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \ - *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \ - *B = IN; CLK = (int) mbedtls_timing_hardclock(); \ - *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \ - *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \ - \ - A = &WALK[PT1 ^ 4]; \ - B = &WALK[PT2 ^ 1]; \ - \ - PTEST = PT2 >> 1; \ - \ - PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \ - PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \ - PTY = (PT2 >> 10) & 7; \ - \ - TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ - TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ - TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ - \ - TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ - TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ - TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ - \ - C = &WALK[PT1 ^ 5]; \ - D = &WALK[PT2 ^ 5]; \ - \ - RES[i++] ^= *A; \ - RES[i++] ^= *B; \ - RES[i++] ^= *C; \ - RES[i++] ^= *D; \ - \ - IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \ - *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \ - *B = IN ^ U2; \ - *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \ - *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \ - \ - A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \ - B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \ - C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \ - D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \ - \ - IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \ - *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \ - *B = IN; \ - *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \ - *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \ - \ - PT1 = ( RES[( i - 8 ) ^ PTX] ^ \ - WALK[PT1 ^ PTX ^ 7] ) & (~1); \ - PT1 ^= (PT2 ^ 0x10) & 0x10; \ - \ - for( n++, i = 0; i < 16; i++ ) \ - hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i]; - -/* - * Entropy gathering function - */ -static void havege_fill( mbedtls_havege_state *hs ) -{ - int i, n = 0; - int U1, U2, *A, *B, *C, *D; - int PT1, PT2, *WALK, RES[16]; - int PTX, PTY, CLK, PTEST, IN; - - WALK = hs->WALK; - PT1 = hs->PT1; - PT2 = hs->PT2; - - PTX = U1 = 0; - PTY = U2 = 0; - - (void)PTX; - - memset( RES, 0, sizeof( RES ) ); - - while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 ) - { - ONE_ITERATION - ONE_ITERATION - ONE_ITERATION - ONE_ITERATION - } - - hs->PT1 = PT1; - hs->PT2 = PT2; - - hs->offset[0] = 0; - hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2; -} - -/* - * HAVEGE initialization - */ -void mbedtls_havege_init( mbedtls_havege_state *hs ) -{ - memset( hs, 0, sizeof( mbedtls_havege_state ) ); - - havege_fill( hs ); -} - -void mbedtls_havege_free( mbedtls_havege_state *hs ) -{ - if( hs == NULL ) - return; - - mbedtls_platform_zeroize( hs, sizeof( mbedtls_havege_state ) ); -} - -/* - * HAVEGE rand function - */ -int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len ) -{ - int val; - size_t use_len; - mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng; - unsigned char *p = buf; - - while( len > 0 ) - { - use_len = len; - if( use_len > sizeof(int) ) - use_len = sizeof(int); - - if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE ) - havege_fill( hs ); - - val = hs->pool[hs->offset[0]++]; - val ^= hs->pool[hs->offset[1]++]; - - memcpy( p, &val, use_len ); - - len -= use_len; - p += use_len; - } - - return( 0 ); -} - -#endif /* MBEDTLS_HAVEGE_C */ diff --git a/library/hkdf.c b/library/hkdf.c deleted file mode 100644 index 82d8a429f4..0000000000 --- a/library/hkdf.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * HKDF implementation -- RFC 5869 - * - * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HKDF_C) - -#include -#include "mbedtls/hkdf.h" -#include "mbedtls/platform_util.h" - -int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, - size_t salt_len, const unsigned char *ikm, size_t ikm_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len ) -{ - int ret; - unsigned char prk[MBEDTLS_MD_MAX_SIZE]; - - ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk ); - - if( ret == 0 ) - { - ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ), - info, info_len, okm, okm_len ); - } - - mbedtls_platform_zeroize( prk, sizeof( prk ) ); - - return( ret ); -} - -int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, - const unsigned char *salt, size_t salt_len, - const unsigned char *ikm, size_t ikm_len, - unsigned char *prk ) -{ - unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' }; - - if( salt == NULL ) - { - size_t hash_len; - - if( salt_len != 0 ) - { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - hash_len = mbedtls_md_get_size( md ); - - if( hash_len == 0 ) - { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - salt = null_salt; - salt_len = hash_len; - } - - return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) ); -} - -int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, - size_t prk_len, const unsigned char *info, - size_t info_len, unsigned char *okm, size_t okm_len ) -{ - size_t hash_len; - size_t where = 0; - size_t n; - size_t t_len = 0; - size_t i; - int ret = 0; - mbedtls_md_context_t ctx; - unsigned char t[MBEDTLS_MD_MAX_SIZE]; - - if( okm == NULL ) - { - return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); - } - - hash_len = mbedtls_md_get_size( md ); - - if( prk_len < hash_len || hash_len == 0 ) - { - return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); - } - - if( info == NULL ) - { - info = (const unsigned char *) ""; - info_len = 0; - } - - n = okm_len / hash_len; - - if( (okm_len % hash_len) != 0 ) - { - n++; - } - - /* - * Per RFC 5869 Section 2.3, okm_len must not exceed - * 255 times the hash length - */ - if( n > 255 ) - { - return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); - } - - mbedtls_md_init( &ctx ); - - if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 ) - { - goto exit; - } - - /* - * Compute T = T(1) | T(2) | T(3) | ... | T(N) - * Where T(N) is defined in RFC 5869 Section 2.3 - */ - for( i = 1; i <= n; i++ ) - { - size_t num_to_copy; - unsigned char c = i & 0xff; - - ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len ); - if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_md_hmac_update( &ctx, t, t_len ); - if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_md_hmac_update( &ctx, info, info_len ); - if( ret != 0 ) - { - goto exit; - } - - /* The constant concatenated to the end of each T(n) is a single octet. - * */ - ret = mbedtls_md_hmac_update( &ctx, &c, 1 ); - if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_md_hmac_finish( &ctx, t ); - if( ret != 0 ) - { - goto exit; - } - - num_to_copy = i != n ? hash_len : okm_len - where; - memcpy( okm + where, t, num_to_copy ); - where += hash_len; - t_len = hash_len; - } - -exit: - mbedtls_md_free( &ctx ); - mbedtls_platform_zeroize( t, sizeof( t ) ); - - return( ret ); -} - -#endif /* MBEDTLS_HKDF_C */ diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c deleted file mode 100644 index c50330e7d8..0000000000 --- a/library/hmac_drbg.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * HMAC_DRBG implementation (NIST SP 800-90) - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * The NIST SP 800-90A DRBGs are described in the following publication. - * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf - * References below are based on rev. 1 (January 2012). - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) - -#include "mbedtls/hmac_drbg.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_SELF_TEST */ -#endif /* MBEDTLS_PLATFORM_C */ - -/* - * HMAC_DRBG context initialization - */ -void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif -} - -/* - * HMAC_DRBG update, using optional additional data (10.1.2.2) - */ -int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); - unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; - unsigned char sep[1]; - unsigned char K[MBEDTLS_MD_MAX_SIZE]; - int ret; - - for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) - { - /* Step 1 or 4 */ - if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - ctx->V, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - sep, 1 ) ) != 0 ) - goto exit; - if( rounds == 2 ) - { - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - additional, add_len ) ) != 0 ) - goto exit; - } - if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 ) - goto exit; - - /* Step 2 or 5 */ - if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - ctx->V, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) - goto exit; - } - -exit: - mbedtls_platform_zeroize( K, sizeof( K ) ); - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len ); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/* - * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) - */ -int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t * md_info, - const unsigned char *data, size_t data_len ) -{ - int ret; - - if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - /* - * Set initial working state. - * Use the V memory location, which is currently all 0, to initialize the - * MD context with an all-zero key. Then set V to its initial value. - */ - if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, - mbedtls_md_get_size( md_info ) ) ) != 0 ) - return( ret ); - memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); - - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman) - */ -int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t len ) -{ - unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; - size_t seedlen; - int ret; - - /* III. Check input length */ - if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || - ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) - { - return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); - } - - memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); - - /* IV. Gather entropy_len bytes of entropy for the seed */ - if( ( ret = ctx->f_entropy( ctx->p_entropy, - seed, ctx->entropy_len ) ) != 0 ) - return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); - - seedlen = ctx->entropy_len; - - /* 1. Concatenate entropy and additional data if any */ - if( additional != NULL && len != 0 ) - { - memcpy( seed + seedlen, additional, len ); - seedlen += len; - } - - /* 2. Update state */ - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 ) - goto exit; - - /* 3. Reset reseed_counter */ - ctx->reseed_counter = 1; - -exit: - /* 4. Done */ - mbedtls_platform_zeroize( seed, seedlen ); - return( ret ); -} - -/* - * HMAC_DRBG initialisation (10.1.2.3 + 9.1) - */ -int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t * md_info, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len ) -{ - int ret; - size_t entropy_len, md_size; - - if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - md_size = mbedtls_md_get_size( md_info ); - - /* - * Set initial working state. - * Use the V memory location, which is currently all 0, to initialize the - * MD context with an all-zero key. Then set V to its initial value. - */ - if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 ) - return( ret ); - memset( ctx->V, 0x01, md_size ); - - ctx->f_entropy = f_entropy; - ctx->p_entropy = p_entropy; - - ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; - - /* - * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by - * each hash function, then according to SP800-90A rev1 10.1 table 2, - * min_entropy_len (in bits) is security_strength. - * - * (This also matches the sizes used in the NIST test vectors.) - */ - entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ - md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ - 32; /* better (256+) -> 256 bits */ - - /* - * For initialisation, use more entropy to emulate a nonce - * (Again, matches test vectors.) - */ - ctx->entropy_len = entropy_len * 3 / 2; - - if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) - return( ret ); - - ctx->entropy_len = entropy_len; - - return( 0 ); -} - -/* - * Set prediction resistance - */ -void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, - int resistance ) -{ - ctx->prediction_resistance = resistance; -} - -/* - * Set entropy length grabbed for reseeds - */ -void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) -{ - ctx->entropy_len = len; -} - -/* - * Set reseed interval - */ -void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) -{ - ctx->reseed_interval = interval; -} - -/* - * HMAC_DRBG random function with optional additional data: - * 10.1.2.5 (arabic) + 9.3 (Roman) - */ -int mbedtls_hmac_drbg_random_with_add( void *p_rng, - unsigned char *output, size_t out_len, - const unsigned char *additional, size_t add_len ) -{ - int ret; - mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; - size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); - size_t left = out_len; - unsigned char *out = output; - - /* II. Check request length */ - if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) - return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); - - /* III. Check input length */ - if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) - return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); - - /* 1. (aka VII and IX) Check reseed counter and PR */ - if( ctx->f_entropy != NULL && /* For no-reseeding instances */ - ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || - ctx->reseed_counter > ctx->reseed_interval ) ) - { - if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) - return( ret ); - - add_len = 0; /* VII.4 */ - } - - /* 2. Use additional data if any */ - if( additional != NULL && add_len != 0 ) - { - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, - additional, add_len ) ) != 0 ) - goto exit; - } - - /* 3, 4, 5. Generate bytes */ - while( left != 0 ) - { - size_t use_len = left > md_len ? md_len : left; - - if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - ctx->V, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) - goto exit; - - memcpy( out, ctx->V, use_len ); - out += use_len; - left -= use_len; - } - - /* 6. Update */ - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, - additional, add_len ) ) != 0 ) - goto exit; - - /* 7. Update reseed counter */ - ctx->reseed_counter++; - -exit: - /* 8. Done */ - return( ret ); -} - -/* - * HMAC_DRBG random function - */ -int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) -{ - int ret; - mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Free an HMAC_DRBG context - */ -void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif - mbedtls_md_free( &ctx->md_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) -{ - int ret; - FILE *f; - unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; - - if( ( f = fopen( path, "wb" ) ) == NULL ) - return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); - - if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) - goto exit; - - if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) - { - ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - goto exit; - } - - ret = 0; - -exit: - fclose( f ); - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} - -int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) -{ - int ret = 0; - FILE *f = NULL; - size_t n; - unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; - unsigned char c; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); - - n = fread( buf, 1, sizeof( buf ), f ); - if( fread( &c, 1, 1, f ) != 0 ) - { - ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; - goto exit; - } - if( n == 0 || ferror( f ) ) - { - ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - goto exit; - } - fclose( f ); - f = NULL; - - ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n ); - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - if( f != NULL ) - fclose( f ); - if( ret != 0 ) - return( ret ); - return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); -} -#endif /* MBEDTLS_FS_IO */ - - -#if defined(MBEDTLS_SELF_TEST) - -#if !defined(MBEDTLS_SHA1_C) -/* Dummy checkup routine */ -int mbedtls_hmac_drbg_self_test( int verbose ) -{ - (void) verbose; - return( 0 ); -} -#else - -#define OUTPUT_LEN 80 - -/* From a NIST PR=true test vector */ -static const unsigned char entropy_pr[] = { - 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, - 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, - 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, - 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, - 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; -static const unsigned char result_pr[OUTPUT_LEN] = { - 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, - 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, - 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, - 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, - 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, - 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, - 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; - -/* From a NIST PR=false test vector */ -static const unsigned char entropy_nopr[] = { - 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, - 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, - 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, - 0xe9, 0x9d, 0xfe, 0xdf }; -static const unsigned char result_nopr[OUTPUT_LEN] = { - 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, - 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, - 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, - 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, - 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, - 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, - 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; - -/* "Entropy" from buffer */ -static size_t test_offset; -static int hmac_drbg_self_test_entropy( void *data, - unsigned char *buf, size_t len ) -{ - const unsigned char *p = data; - memcpy( buf, p + test_offset, len ); - test_offset += len; - return( 0 ); -} - -#define CHK( c ) if( (c) != 0 ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf( "failed\n" ); \ - return( 1 ); \ - } - -/* - * Checkup routine for HMAC_DRBG with SHA-1 - */ -int mbedtls_hmac_drbg_self_test( int verbose ) -{ - mbedtls_hmac_drbg_context ctx; - unsigned char buf[OUTPUT_LEN]; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); - - mbedtls_hmac_drbg_init( &ctx ); - - /* - * PR = True - */ - if( verbose != 0 ) - mbedtls_printf( " HMAC_DRBG (PR = True) : " ); - - test_offset = 0; - CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, - hmac_drbg_self_test_entropy, (void *) entropy_pr, - NULL, 0 ) ); - mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); - mbedtls_hmac_drbg_free( &ctx ); - - mbedtls_hmac_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - /* - * PR = False - */ - if( verbose != 0 ) - mbedtls_printf( " HMAC_DRBG (PR = False) : " ); - - mbedtls_hmac_drbg_init( &ctx ); - - test_offset = 0; - CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, - hmac_drbg_self_test_entropy, (void *) entropy_nopr, - NULL, 0 ) ); - CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); - mbedtls_hmac_drbg_free( &ctx ); - - mbedtls_hmac_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_HMAC_DRBG_C */ diff --git a/library/md.c b/library/md.c deleted file mode 100644 index 303cdcbeeb..0000000000 --- a/library/md.c +++ /dev/null @@ -1,475 +0,0 @@ -/** - * \file mbedtls_md.c - * - * \brief Generic message digest wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD_C) - -#include "mbedtls/md.h" -#include "mbedtls/md_internal.h" -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -/* - * Reminder: update profiles in x509_crt.c when adding a new hash! - */ -static const int supported_digests[] = { - -#if defined(MBEDTLS_SHA512_C) - MBEDTLS_MD_SHA512, - MBEDTLS_MD_SHA384, -#endif - -#if defined(MBEDTLS_SHA256_C) - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA224, -#endif - -#if defined(MBEDTLS_SHA1_C) - MBEDTLS_MD_SHA1, -#endif - -#if defined(MBEDTLS_RIPEMD160_C) - MBEDTLS_MD_RIPEMD160, -#endif - -#if defined(MBEDTLS_MD5_C) - MBEDTLS_MD_MD5, -#endif - -#if defined(MBEDTLS_MD4_C) - MBEDTLS_MD_MD4, -#endif - -#if defined(MBEDTLS_MD2_C) - MBEDTLS_MD_MD2, -#endif - - MBEDTLS_MD_NONE -}; - -const int *mbedtls_md_list( void ) -{ - return( supported_digests ); -} - -const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) -{ - if( NULL == md_name ) - return( NULL ); - - /* Get the appropriate digest information */ -#if defined(MBEDTLS_MD2_C) - if( !strcmp( "MD2", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); -#endif -#if defined(MBEDTLS_MD4_C) - if( !strcmp( "MD4", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); -#endif -#if defined(MBEDTLS_MD5_C) - if( !strcmp( "MD5", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - if( !strcmp( "RIPEMD160", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); -#endif -#if defined(MBEDTLS_SHA1_C) - if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); -#endif -#if defined(MBEDTLS_SHA256_C) - if( !strcmp( "SHA224", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); - if( !strcmp( "SHA256", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); -#endif -#if defined(MBEDTLS_SHA512_C) - if( !strcmp( "SHA384", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); - if( !strcmp( "SHA512", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); -#endif - return( NULL ); -} - -const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) -{ - switch( md_type ) - { -#if defined(MBEDTLS_MD2_C) - case MBEDTLS_MD_MD2: - return( &mbedtls_md2_info ); -#endif -#if defined(MBEDTLS_MD4_C) - case MBEDTLS_MD_MD4: - return( &mbedtls_md4_info ); -#endif -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return( &mbedtls_md5_info ); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - return( &mbedtls_ripemd160_info ); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return( &mbedtls_sha1_info ); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA224: - return( &mbedtls_sha224_info ); - case MBEDTLS_MD_SHA256: - return( &mbedtls_sha256_info ); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA384: - return( &mbedtls_sha384_info ); - case MBEDTLS_MD_SHA512: - return( &mbedtls_sha512_info ); -#endif - default: - return( NULL ); - } -} - -void mbedtls_md_init( mbedtls_md_context_t *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); -} - -void mbedtls_md_free( mbedtls_md_context_t *ctx ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return; - - if( ctx->md_ctx != NULL ) - ctx->md_info->ctx_free_func( ctx->md_ctx ); - - if( ctx->hmac_ctx != NULL ) - { - mbedtls_platform_zeroize( ctx->hmac_ctx, - 2 * ctx->md_info->block_size ); - mbedtls_free( ctx->hmac_ctx ); - } - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); -} - -int mbedtls_md_clone( mbedtls_md_context_t *dst, - const mbedtls_md_context_t *src ) -{ - if( dst == NULL || dst->md_info == NULL || - src == NULL || src->md_info == NULL || - dst->md_info != src->md_info ) - { - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - } - - dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); - - return( 0 ); -} - -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) -{ - return mbedtls_md_setup( ctx, md_info, 1 ); -} -#endif - -int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) -{ - if( md_info == NULL || ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); - - if( hmac != 0 ) - { - ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); - if( ctx->hmac_ctx == NULL ) - { - md_info->ctx_free_func( ctx->md_ctx ); - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); - } - } - - ctx->md_info = md_info; - - return( 0 ); -} - -int mbedtls_md_starts( mbedtls_md_context_t *ctx ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->starts_func( ctx->md_ctx ) ); -} - -int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); -} - -int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); -} - -int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - if( md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( md_info->digest_func( input, ilen, output ) ); -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) -{ - int ret; - FILE *f; - size_t n; - mbedtls_md_context_t ctx; - unsigned char buf[1024]; - - if( md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); - - mbedtls_md_init( &ctx ); - - if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) - goto cleanup; - - if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) - goto cleanup; - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) - goto cleanup; - - if( ferror( f ) != 0 ) - ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; - else - ret = md_info->finish_func( ctx.md_ctx, output ); - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - fclose( f ); - mbedtls_md_free( &ctx ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) -{ - int ret; - unsigned char sum[MBEDTLS_MD_MAX_SIZE]; - unsigned char *ipad, *opad; - size_t i; - - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - if( keylen > (size_t) ctx->md_info->block_size ) - { - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - goto cleanup; - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) - goto cleanup; - if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) - goto cleanup; - - keylen = ctx->md_info->size; - key = sum; - } - - ipad = (unsigned char *) ctx->hmac_ctx; - opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - - memset( ipad, 0x36, ctx->md_info->block_size ); - memset( opad, 0x5C, ctx->md_info->block_size ); - - for( i = 0; i < keylen; i++ ) - { - ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); - opad[i] = (unsigned char)( opad[i] ^ key[i] ); - } - - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - goto cleanup; - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, - ctx->md_info->block_size ) ) != 0 ) - goto cleanup; - -cleanup: - mbedtls_platform_zeroize( sum, sizeof( sum ) ); - - return( ret ); -} - -int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) -{ - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); -} - -int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) -{ - int ret; - unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; - unsigned char *opad; - - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - - if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) - return( ret ); - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - return( ret ); - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, - ctx->md_info->block_size ) ) != 0 ) - return( ret ); - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, - ctx->md_info->size ) ) != 0 ) - return( ret ); - return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); -} - -int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) -{ - int ret; - unsigned char *ipad; - - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - ipad = (unsigned char *) ctx->hmac_ctx; - - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - return( ret ); - return( ctx->md_info->update_func( ctx->md_ctx, ipad, - ctx->md_info->block_size ) ); -} - -int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - mbedtls_md_context_t ctx; - int ret; - - if( md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - mbedtls_md_init( &ctx ); - - if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) - goto cleanup; - - if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) - goto cleanup; - -cleanup: - mbedtls_md_free( &ctx ); - - return( ret ); -} - -int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->process_func( ctx->md_ctx, data ) ); -} - -unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) -{ - if( md_info == NULL ) - return( 0 ); - - return md_info->size; -} - -mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) -{ - if( md_info == NULL ) - return( MBEDTLS_MD_NONE ); - - return md_info->type; -} - -const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) -{ - if( md_info == NULL ) - return( NULL ); - - return md_info->name; -} - -#endif /* MBEDTLS_MD_C */ diff --git a/library/md2.c b/library/md2.c deleted file mode 100644 index 1c0b3df52d..0000000000 --- a/library/md2.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * RFC 1115/1319 compliant MD2 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The MD2 algorithm was designed by Ron Rivest in 1989. - * - * http://www.ietf.org/rfc/rfc1115.txt - * http://www.ietf.org/rfc/rfc1319.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD2_C) - -#include "mbedtls/md2.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_MD2_ALT) - -static const unsigned char PI_SUBST[256] = -{ - 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, - 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, - 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, - 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, - 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, - 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, - 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, - 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, - 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, - 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, - 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, - 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, - 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, - 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, - 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, - 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, - 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, - 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, - 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, - 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, - 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, - 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, - 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, - 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, - 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, - 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 -}; - -void mbedtls_md2_init( mbedtls_md2_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md2_context ) ); -} - -void mbedtls_md2_free( mbedtls_md2_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md2_context ) ); -} - -void mbedtls_md2_clone( mbedtls_md2_context *dst, - const mbedtls_md2_context *src ) -{ - *dst = *src; -} - -/* - * MD2 context setup - */ -int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ) -{ - memset( ctx->cksum, 0, 16 ); - memset( ctx->state, 0, 46 ); - memset( ctx->buffer, 0, 16 ); - ctx->left = 0; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_starts( mbedtls_md2_context *ctx ) -{ - mbedtls_md2_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_MD2_PROCESS_ALT) -int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) -{ - int i, j; - unsigned char t = 0; - - for( i = 0; i < 16; i++ ) - { - ctx->state[i + 16] = ctx->buffer[i]; - ctx->state[i + 32] = - (unsigned char)( ctx->buffer[i] ^ ctx->state[i]); - } - - for( i = 0; i < 18; i++ ) - { - for( j = 0; j < 48; j++ ) - { - ctx->state[j] = (unsigned char) - ( ctx->state[j] ^ PI_SUBST[t] ); - t = ctx->state[j]; - } - - t = (unsigned char)( t + i ); - } - - t = ctx->cksum[15]; - - for( i = 0; i < 16; i++ ) - { - ctx->cksum[i] = (unsigned char) - ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] ); - t = ctx->cksum[i]; - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_process( mbedtls_md2_context *ctx ) -{ - mbedtls_internal_md2_process( ctx ); -} -#endif -#endif /* !MBEDTLS_MD2_PROCESS_ALT */ - -/* - * MD2 process buffer - */ -int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - - while( ilen > 0 ) - { - if( ilen > 16 - ctx->left ) - fill = 16 - ctx->left; - else - fill = ilen; - - memcpy( ctx->buffer + ctx->left, input, fill ); - - ctx->left += fill; - input += fill; - ilen -= fill; - - if( ctx->left == 16 ) - { - ctx->left = 0; - if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) - return( ret ); - } - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_update( mbedtls_md2_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md2_update_ret( ctx, input, ilen ); -} -#endif - -/* - * MD2 final digest - */ -int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, - unsigned char output[16] ) -{ - int ret; - size_t i; - unsigned char x; - - x = (unsigned char)( 16 - ctx->left ); - - for( i = ctx->left; i < 16; i++ ) - ctx->buffer[i] = x; - - if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) - return( ret ); - - memcpy( ctx->buffer, ctx->cksum, 16 ); - if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) - return( ret ); - - memcpy( output, ctx->state, 16 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_finish( mbedtls_md2_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md2_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_MD2_ALT */ - -/* - * output = MD2( input buffer ) - */ -int mbedtls_md2_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - int ret; - mbedtls_md2_context ctx; - - mbedtls_md2_init( &ctx ); - - if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_md2_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md2_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) - -/* - * RFC 1319 test vectors - */ -static const unsigned char md2_test_str[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } -}; - -static const size_t md2_test_strlen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md2_test_sum[7][16] = -{ - { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D, - 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 }, - { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72, - 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 }, - { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B, - 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB }, - { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B, - 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 }, - { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB, - 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B }, - { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39, - 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD }, - { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D, - 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 } -}; - -/* - * Checkup routine - */ -int mbedtls_md2_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char md2sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " MD2 test #%d: ", i + 1 ); - - ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum ); - if( ret != 0 ) - goto fail; - - if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD2_C */ diff --git a/library/md4.c b/library/md4.c deleted file mode 100644 index 828fd42999..0000000000 --- a/library/md4.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * RFC 1186/1320 compliant MD4 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The MD4 algorithm was designed by Ron Rivest in 1990. - * - * http://www.ietf.org/rfc/rfc1186.txt - * http://www.ietf.org/rfc/rfc1320.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD4_C) - -#include "mbedtls/md4.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_MD4_ALT) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -void mbedtls_md4_init( mbedtls_md4_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md4_context ) ); -} - -void mbedtls_md4_free( mbedtls_md4_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) ); -} - -void mbedtls_md4_clone( mbedtls_md4_context *dst, - const mbedtls_md4_context *src ) -{ - *dst = *src; -} - -/* - * MD4 context setup - */ -int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_starts( mbedtls_md4_context *ctx ) -{ - mbedtls_md4_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_MD4_PROCESS_ALT) -int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, - const unsigned char data[64] ) -{ - uint32_t X[16], A, B, C, D; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); - -#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z))) -#define P(a,b,c,d,x,s) \ - do \ - { \ - (a) += F((b),(c),(d)) + (x); \ - (a) = S((a),(s)); \ - } while( 0 ) - - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 1], 7 ); - P( C, D, A, B, X[ 2], 11 ); - P( B, C, D, A, X[ 3], 19 ); - P( A, B, C, D, X[ 4], 3 ); - P( D, A, B, C, X[ 5], 7 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[ 7], 19 ); - P( A, B, C, D, X[ 8], 3 ); - P( D, A, B, C, X[ 9], 7 ); - P( C, D, A, B, X[10], 11 ); - P( B, C, D, A, X[11], 19 ); - P( A, B, C, D, X[12], 3 ); - P( D, A, B, C, X[13], 7 ); - P( C, D, A, B, X[14], 11 ); - P( B, C, D, A, X[15], 19 ); - -#undef P -#undef F - -#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -#define P(a,b,c,d,x,s) \ - do \ - { \ - (a) += F((b),(c),(d)) + (x) + 0x5A827999; \ - (a) = S((a),(s)); \ - } while( 0 ) - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 4], 5 ); - P( C, D, A, B, X[ 8], 9 ); - P( B, C, D, A, X[12], 13 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 5], 5 ); - P( C, D, A, B, X[ 9], 9 ); - P( B, C, D, A, X[13], 13 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[ 6], 5 ); - P( C, D, A, B, X[10], 9 ); - P( B, C, D, A, X[14], 13 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[ 7], 5 ); - P( C, D, A, B, X[11], 9 ); - P( B, C, D, A, X[15], 13 ); - -#undef P -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) -#define P(a,b,c,d,x,s) \ - do \ - { \ - (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \ - (a) = S((a),(s)); \ - } while( 0 ) - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 8], 9 ); - P( C, D, A, B, X[ 4], 11 ); - P( B, C, D, A, X[12], 15 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[10], 9 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[14], 15 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 9], 9 ); - P( C, D, A, B, X[ 5], 11 ); - P( B, C, D, A, X[13], 15 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[11], 9 ); - P( C, D, A, B, X[ 7], 11 ); - P( B, C, D, A, X[15], 15 ); - -#undef F -#undef P - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_process( mbedtls_md4_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_md4_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_MD4_PROCESS_ALT */ - -/* - * MD4 process buffer - */ -int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - - if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, ilen ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_update( mbedtls_md4_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md4_update_ret( ctx, input, ilen ); -} -#endif - -static const unsigned char md4_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD4 final digest - */ -int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, - unsigned char output[16] ) -{ - int ret; - uint32_t last, padn; - uint32_t high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn ); - if( ret != 0 ) - return( ret ); - - if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 ) - return( ret ); - - - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_finish( mbedtls_md4_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md4_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_MD4_ALT */ - -/* - * output = MD4( input buffer ) - */ -int mbedtls_md4_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - int ret; - mbedtls_md4_context ctx; - - mbedtls_md4_init( &ctx ); - - if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_md4_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md4_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) - -/* - * RFC 1320 test vectors - */ -static const unsigned char md4_test_str[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } -}; - -static const size_t md4_test_strlen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md4_test_sum[7][16] = -{ - { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, - 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, - { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, - 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, - { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, - 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, - { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, - 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, - { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, - 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, - { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, - 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, - { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, - 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } -}; - -/* - * Checkup routine - */ -int mbedtls_md4_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char md4sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " MD4 test #%d: ", i + 1 ); - - ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum ); - if( ret != 0 ) - goto fail; - - if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD4_C */ diff --git a/library/md5.c b/library/md5.c deleted file mode 100644 index a93da8a061..0000000000 --- a/library/md5.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD5_C) - -#include "mbedtls/md5.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_MD5_ALT) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -void mbedtls_md5_init( mbedtls_md5_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md5_context ) ); -} - -void mbedtls_md5_free( mbedtls_md5_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) ); -} - -void mbedtls_md5_clone( mbedtls_md5_context *dst, - const mbedtls_md5_context *src ) -{ - *dst = *src; -} - -/* - * MD5 context setup - */ -int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_starts( mbedtls_md5_context *ctx ) -{ - mbedtls_md5_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_MD5_PROCESS_ALT) -int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, - const unsigned char data[64] ) -{ - uint32_t X[16], A, B, C, D; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); - -#define S(x,n) \ - ( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) ) - -#define P(a,b,c,d,k,s,t) \ - do \ - { \ - (a) += F((b),(c),(d)) + X[(k)] + (t); \ - (a) = S((a),(s)) + (b); \ - } while( 0 ) - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y)))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) ((y) ^ ((x) | ~(z))) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_process( mbedtls_md5_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_md5_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_MD5_PROCESS_ALT */ - -/* - * MD5 process buffer - */ -int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), input, ilen ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_update( mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md5_update_ret( ctx, input, ilen ); -} -#endif - -/* - * MD5 final digest - */ -int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, - unsigned char output[16] ) -{ - int ret; - uint32_t used; - uint32_t high, low; - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if( used <= 56 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 56 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 64 - used ); - - if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 56 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, ctx->buffer, 56 ); - PUT_UINT32_LE( high, ctx->buffer, 60 ); - - if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_finish( mbedtls_md5_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md5_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_MD5_ALT */ - -/* - * output = MD5( input buffer ) - */ -int mbedtls_md5_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - int ret; - mbedtls_md5_context ctx; - - mbedtls_md5_init( &ctx ); - - if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_md5_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md5_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * RFC 1321 test vectors - */ -static const unsigned char md5_test_buf[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } -}; - -static const size_t md5_test_buflen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md5_test_sum[7][16] = -{ - { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, - 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, - { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, - 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, - { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, - 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, - { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, - 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, - { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, - 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, - { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, - 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, - { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, - 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } -}; - -/* - * Checkup routine - */ -int mbedtls_md5_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char md5sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " MD5 test #%d: ", i + 1 ); - - ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum ); - if( ret != 0 ) - goto fail; - - if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD5_C */ diff --git a/library/md_wrap.c b/library/md_wrap.c deleted file mode 100644 index 32f0871976..0000000000 --- a/library/md_wrap.c +++ /dev/null @@ -1,586 +0,0 @@ -/** - * \file md_wrap.c - * - * \brief Generic message digest wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD_C) - -#include "mbedtls/md_internal.h" - -#if defined(MBEDTLS_MD2_C) -#include "mbedtls/md2.h" -#endif - -#if defined(MBEDTLS_MD4_C) -#include "mbedtls/md4.h" -#endif - -#if defined(MBEDTLS_MD5_C) -#include "mbedtls/md5.h" -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#include "mbedtls/ripemd160.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "mbedtls/sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "mbedtls/sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "mbedtls/sha512.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_MD2_C) - -static int md2_starts_wrap( void *ctx ) -{ - return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) ); -} - -static int md2_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) ); -} - -static int md2_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) ); -} - -static void *md2_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) ); - - if( ctx != NULL ) - mbedtls_md2_init( (mbedtls_md2_context *) ctx ); - - return( ctx ); -} - -static void md2_ctx_free( void *ctx ) -{ - mbedtls_md2_free( (mbedtls_md2_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md2_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md2_clone( (mbedtls_md2_context *) dst, - (const mbedtls_md2_context *) src ); -} - -static int md2_process_wrap( void *ctx, const unsigned char *data ) -{ - ((void) data); - - return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) ); -} - -const mbedtls_md_info_t mbedtls_md2_info = { - MBEDTLS_MD_MD2, - "MD2", - 16, - 16, - md2_starts_wrap, - md2_update_wrap, - md2_finish_wrap, - mbedtls_md2_ret, - md2_ctx_alloc, - md2_ctx_free, - md2_clone_wrap, - md2_process_wrap, -}; - -#endif /* MBEDTLS_MD2_C */ - -#if defined(MBEDTLS_MD4_C) - -static int md4_starts_wrap( void *ctx ) -{ - return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) ); -} - -static int md4_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) ); -} - -static int md4_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) ); -} - -static void *md4_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) ); - - if( ctx != NULL ) - mbedtls_md4_init( (mbedtls_md4_context *) ctx ); - - return( ctx ); -} - -static void md4_ctx_free( void *ctx ) -{ - mbedtls_md4_free( (mbedtls_md4_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md4_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md4_clone( (mbedtls_md4_context *) dst, - (const mbedtls_md4_context *) src ); -} - -static int md4_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_md4_info = { - MBEDTLS_MD_MD4, - "MD4", - 16, - 64, - md4_starts_wrap, - md4_update_wrap, - md4_finish_wrap, - mbedtls_md4_ret, - md4_ctx_alloc, - md4_ctx_free, - md4_clone_wrap, - md4_process_wrap, -}; - -#endif /* MBEDTLS_MD4_C */ - -#if defined(MBEDTLS_MD5_C) - -static int md5_starts_wrap( void *ctx ) -{ - return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) ); -} - -static int md5_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) ); -} - -static int md5_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) ); -} - -static void *md5_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) ); - - if( ctx != NULL ) - mbedtls_md5_init( (mbedtls_md5_context *) ctx ); - - return( ctx ); -} - -static void md5_ctx_free( void *ctx ) -{ - mbedtls_md5_free( (mbedtls_md5_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md5_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md5_clone( (mbedtls_md5_context *) dst, - (const mbedtls_md5_context *) src ); -} - -static int md5_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_md5_info = { - MBEDTLS_MD_MD5, - "MD5", - 16, - 64, - md5_starts_wrap, - md5_update_wrap, - md5_finish_wrap, - mbedtls_md5_ret, - md5_ctx_alloc, - md5_ctx_free, - md5_clone_wrap, - md5_process_wrap, -}; - -#endif /* MBEDTLS_MD5_C */ - -#if defined(MBEDTLS_RIPEMD160_C) - -static int ripemd160_starts_wrap( void *ctx ) -{ - return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) ); -} - -static int ripemd160_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx, - input, ilen ) ); -} - -static int ripemd160_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx, - output ) ); -} - -static void *ripemd160_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) ); - - if( ctx != NULL ) - mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx ); - - return( ctx ); -} - -static void ripemd160_ctx_free( void *ctx ) -{ - mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx ); - mbedtls_free( ctx ); -} - -static void ripemd160_clone_wrap( void *dst, const void *src ) -{ - mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst, - (const mbedtls_ripemd160_context *) src ); -} - -static int ripemd160_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_ripemd160_process( - (mbedtls_ripemd160_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_ripemd160_info = { - MBEDTLS_MD_RIPEMD160, - "RIPEMD160", - 20, - 64, - ripemd160_starts_wrap, - ripemd160_update_wrap, - ripemd160_finish_wrap, - mbedtls_ripemd160_ret, - ripemd160_ctx_alloc, - ripemd160_ctx_free, - ripemd160_clone_wrap, - ripemd160_process_wrap, -}; - -#endif /* MBEDTLS_RIPEMD160_C */ - -#if defined(MBEDTLS_SHA1_C) - -static int sha1_starts_wrap( void *ctx ) -{ - return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) ); -} - -static int sha1_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx, - input, ilen ) ); -} - -static int sha1_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) ); -} - -static void *sha1_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) ); - - if( ctx != NULL ) - mbedtls_sha1_init( (mbedtls_sha1_context *) ctx ); - - return( ctx ); -} - -static void sha1_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha1_clone( (mbedtls_sha1_context *) dst, - (const mbedtls_sha1_context *) src ); -} - -static void sha1_ctx_free( void *ctx ) -{ - mbedtls_sha1_free( (mbedtls_sha1_context *) ctx ); - mbedtls_free( ctx ); -} - -static int sha1_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha1_info = { - MBEDTLS_MD_SHA1, - "SHA1", - 20, - 64, - sha1_starts_wrap, - sha1_update_wrap, - sha1_finish_wrap, - mbedtls_sha1_ret, - sha1_ctx_alloc, - sha1_ctx_free, - sha1_clone_wrap, - sha1_process_wrap, -}; - -#endif /* MBEDTLS_SHA1_C */ - -/* - * Wrappers for generic message digests - */ -#if defined(MBEDTLS_SHA256_C) - -static int sha224_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) ); -} - -static int sha224_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx, - input, ilen ) ); -} - -static int sha224_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx, - output ) ); -} - -static int sha224_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 1 ) ); -} - -static void *sha224_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); - - if( ctx != NULL ) - mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); - - return( ctx ); -} - -static void sha224_ctx_free( void *ctx ) -{ - mbedtls_sha256_free( (mbedtls_sha256_context *) ctx ); - mbedtls_free( ctx ); -} - -static void sha224_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha256_clone( (mbedtls_sha256_context *) dst, - (const mbedtls_sha256_context *) src ); -} - -static int sha224_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha224_info = { - MBEDTLS_MD_SHA224, - "SHA224", - 28, - 64, - sha224_starts_wrap, - sha224_update_wrap, - sha224_finish_wrap, - sha224_wrap, - sha224_ctx_alloc, - sha224_ctx_free, - sha224_clone_wrap, - sha224_process_wrap, -}; - -static int sha256_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) ); -} - -static int sha256_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); -} - -const mbedtls_md_info_t mbedtls_sha256_info = { - MBEDTLS_MD_SHA256, - "SHA256", - 32, - 64, - sha256_starts_wrap, - sha224_update_wrap, - sha224_finish_wrap, - sha256_wrap, - sha224_ctx_alloc, - sha224_ctx_free, - sha224_clone_wrap, - sha224_process_wrap, -}; - -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - -static int sha384_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) ); -} - -static int sha384_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx, - input, ilen ) ); -} - -static int sha384_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx, - output ) ); -} - -static int sha384_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 1 ) ); -} - -static void *sha384_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) ); - - if( ctx != NULL ) - mbedtls_sha512_init( (mbedtls_sha512_context *) ctx ); - - return( ctx ); -} - -static void sha384_ctx_free( void *ctx ) -{ - mbedtls_sha512_free( (mbedtls_sha512_context *) ctx ); - mbedtls_free( ctx ); -} - -static void sha384_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha512_clone( (mbedtls_sha512_context *) dst, - (const mbedtls_sha512_context *) src ); -} - -static int sha384_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha384_info = { - MBEDTLS_MD_SHA384, - "SHA384", - 48, - 128, - sha384_starts_wrap, - sha384_update_wrap, - sha384_finish_wrap, - sha384_wrap, - sha384_ctx_alloc, - sha384_ctx_free, - sha384_clone_wrap, - sha384_process_wrap, -}; - -static int sha512_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) ); -} - -static int sha512_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); -} - -const mbedtls_md_info_t mbedtls_sha512_info = { - MBEDTLS_MD_SHA512, - "SHA512", - 64, - 128, - sha512_starts_wrap, - sha384_update_wrap, - sha384_finish_wrap, - sha512_wrap, - sha384_ctx_alloc, - sha384_ctx_free, - sha384_clone_wrap, - sha384_process_wrap, -}; - -#endif /* MBEDTLS_SHA512_C */ - -#endif /* MBEDTLS_MD_C */ diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c deleted file mode 100644 index 51ea7c41d7..0000000000 --- a/library/memory_buffer_alloc.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Buffer-based memory allocator - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#include "mbedtls/memory_buffer_alloc.h" - -/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C - is dependent upon MBEDTLS_PLATFORM_C */ -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_MEMORY_BACKTRACE) -#include -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#define MAGIC1 0xFF00AA55 -#define MAGIC2 0xEE119966 -#define MAX_BT 20 - -typedef struct _memory_header memory_header; -struct _memory_header -{ - size_t magic1; - size_t size; - size_t alloc; - memory_header *prev; - memory_header *next; - memory_header *prev_free; - memory_header *next_free; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - char **trace; - size_t trace_count; -#endif - size_t magic2; -}; - -typedef struct -{ - unsigned char *buf; - size_t len; - memory_header *first; - memory_header *first_free; - int verify; -#if defined(MBEDTLS_MEMORY_DEBUG) - size_t alloc_count; - size_t free_count; - size_t total_used; - size_t maximum_used; - size_t header_count; - size_t maximum_header_count; -#endif -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; -#endif -} -buffer_alloc_ctx; - -static buffer_alloc_ctx heap; - -#if defined(MBEDTLS_MEMORY_DEBUG) -static void debug_header( memory_header *hdr ) -{ -#if defined(MBEDTLS_MEMORY_BACKTRACE) - size_t i; -#endif - - mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), " - "ALLOC(%zu), SIZE(%10zu)\n", - (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, - hdr->alloc, hdr->size ); - mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n", - (size_t) hdr->prev_free, (size_t) hdr->next_free ); - -#if defined(MBEDTLS_MEMORY_BACKTRACE) - mbedtls_fprintf( stderr, "TRACE: \n" ); - for( i = 0; i < hdr->trace_count; i++ ) - mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] ); - mbedtls_fprintf( stderr, "\n" ); -#endif -} - -static void debug_chain( void ) -{ - memory_header *cur = heap.first; - - mbedtls_fprintf( stderr, "\nBlock list\n" ); - while( cur != NULL ) - { - debug_header( cur ); - cur = cur->next; - } - - mbedtls_fprintf( stderr, "Free list\n" ); - cur = heap.first_free; - - while( cur != NULL ) - { - debug_header( cur ); - cur = cur->next_free; - } -} -#endif /* MBEDTLS_MEMORY_DEBUG */ - -static int verify_header( memory_header *hdr ) -{ - if( hdr->magic1 != MAGIC1 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); -#endif - return( 1 ); - } - - if( hdr->magic2 != MAGIC2 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); -#endif - return( 1 ); - } - - if( hdr->alloc > 1 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" ); -#endif - return( 1 ); - } - - if( hdr->prev != NULL && hdr->prev == hdr->next ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: prev == next\n" ); -#endif - return( 1 ); - } - - if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" ); -#endif - return( 1 ); - } - - return( 0 ); -} - -static int verify_chain( void ) -{ - memory_header *prv = heap.first, *cur; - - if( prv == NULL || verify_header( prv ) != 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification of first header " - "failed\n" ); -#endif - return( 1 ); - } - - if( heap.first->prev != NULL ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification failed: " - "first->prev != NULL\n" ); -#endif - return( 1 ); - } - - cur = heap.first->next; - - while( cur != NULL ) - { - if( verify_header( cur ) != 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification of header " - "failed\n" ); -#endif - return( 1 ); - } - - if( cur->prev != prv ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification failed: " - "cur->prev != prv\n" ); -#endif - return( 1 ); - } - - prv = cur; - cur = cur->next; - } - - return( 0 ); -} - -static void *buffer_alloc_calloc( size_t n, size_t size ) -{ - memory_header *new, *cur = heap.first_free; - unsigned char *p; - void *ret; - size_t original_len, len; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - void *trace_buffer[MAX_BT]; - size_t trace_cnt; -#endif - - if( heap.buf == NULL || heap.first == NULL ) - return( NULL ); - - original_len = len = n * size; - - if( n == 0 || size == 0 || len / n != size ) - return( NULL ); - else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - return( NULL ); - - if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - { - len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - len += MBEDTLS_MEMORY_ALIGN_MULTIPLE; - } - - // Find block that fits - // - while( cur != NULL ) - { - if( cur->size >= len ) - break; - - cur = cur->next_free; - } - - if( cur == NULL ) - return( NULL ); - - if( cur->alloc != 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated " - "data\n" ); -#endif - mbedtls_exit( 1 ); - } - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.alloc_count++; -#endif - - // Found location, split block if > memory_header + 4 room left - // - if( cur->size - len < sizeof(memory_header) + - MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - { - cur->alloc = 1; - - // Remove from free_list - // - if( cur->prev_free != NULL ) - cur->prev_free->next_free = cur->next_free; - else - heap.first_free = cur->next_free; - - if( cur->next_free != NULL ) - cur->next_free->prev_free = cur->prev_free; - - cur->prev_free = NULL; - cur->next_free = NULL; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.total_used += cur->size; - if( heap.total_used > heap.maximum_used ) - heap.maximum_used = heap.total_used; -#endif -#if defined(MBEDTLS_MEMORY_BACKTRACE) - trace_cnt = backtrace( trace_buffer, MAX_BT ); - cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); - cur->trace_count = trace_cnt; -#endif - - if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) - mbedtls_exit( 1 ); - - ret = (unsigned char *) cur + sizeof( memory_header ); - memset( ret, 0, original_len ); - - return( ret ); - } - - p = ( (unsigned char *) cur ) + sizeof(memory_header) + len; - new = (memory_header *) p; - - new->size = cur->size - len - sizeof(memory_header); - new->alloc = 0; - new->prev = cur; - new->next = cur->next; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - new->trace = NULL; - new->trace_count = 0; -#endif - new->magic1 = MAGIC1; - new->magic2 = MAGIC2; - - if( new->next != NULL ) - new->next->prev = new; - - // Replace cur with new in free_list - // - new->prev_free = cur->prev_free; - new->next_free = cur->next_free; - if( new->prev_free != NULL ) - new->prev_free->next_free = new; - else - heap.first_free = new; - - if( new->next_free != NULL ) - new->next_free->prev_free = new; - - cur->alloc = 1; - cur->size = len; - cur->next = new; - cur->prev_free = NULL; - cur->next_free = NULL; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count++; - if( heap.header_count > heap.maximum_header_count ) - heap.maximum_header_count = heap.header_count; - heap.total_used += cur->size; - if( heap.total_used > heap.maximum_used ) - heap.maximum_used = heap.total_used; -#endif -#if defined(MBEDTLS_MEMORY_BACKTRACE) - trace_cnt = backtrace( trace_buffer, MAX_BT ); - cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); - cur->trace_count = trace_cnt; -#endif - - if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) - mbedtls_exit( 1 ); - - ret = (unsigned char *) cur + sizeof( memory_header ); - memset( ret, 0, original_len ); - - return( ret ); -} - -static void buffer_alloc_free( void *ptr ) -{ - memory_header *hdr, *old = NULL; - unsigned char *p = (unsigned char *) ptr; - - if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) - return; - - if( p < heap.buf || p >= heap.buf + heap.len ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " - "space\n" ); -#endif - mbedtls_exit( 1 ); - } - - p -= sizeof(memory_header); - hdr = (memory_header *) p; - - if( verify_header( hdr ) != 0 ) - mbedtls_exit( 1 ); - - if( hdr->alloc != 1 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated " - "data\n" ); -#endif - mbedtls_exit( 1 ); - } - - hdr->alloc = 0; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.free_count++; - heap.total_used -= hdr->size; -#endif - -#if defined(MBEDTLS_MEMORY_BACKTRACE) - free( hdr->trace ); - hdr->trace = NULL; - hdr->trace_count = 0; -#endif - - // Regroup with block before - // - if( hdr->prev != NULL && hdr->prev->alloc == 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count--; -#endif - hdr->prev->size += sizeof(memory_header) + hdr->size; - hdr->prev->next = hdr->next; - old = hdr; - hdr = hdr->prev; - - if( hdr->next != NULL ) - hdr->next->prev = hdr; - - memset( old, 0, sizeof(memory_header) ); - } - - // Regroup with block after - // - if( hdr->next != NULL && hdr->next->alloc == 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count--; -#endif - hdr->size += sizeof(memory_header) + hdr->next->size; - old = hdr->next; - hdr->next = hdr->next->next; - - if( hdr->prev_free != NULL || hdr->next_free != NULL ) - { - if( hdr->prev_free != NULL ) - hdr->prev_free->next_free = hdr->next_free; - else - heap.first_free = hdr->next_free; - - if( hdr->next_free != NULL ) - hdr->next_free->prev_free = hdr->prev_free; - } - - hdr->prev_free = old->prev_free; - hdr->next_free = old->next_free; - - if( hdr->prev_free != NULL ) - hdr->prev_free->next_free = hdr; - else - heap.first_free = hdr; - - if( hdr->next_free != NULL ) - hdr->next_free->prev_free = hdr; - - if( hdr->next != NULL ) - hdr->next->prev = hdr; - - memset( old, 0, sizeof(memory_header) ); - } - - // Prepend to free_list if we have not merged - // (Does not have to stay in same order as prev / next list) - // - if( old == NULL ) - { - hdr->next_free = heap.first_free; - if( heap.first_free != NULL ) - heap.first_free->prev_free = hdr; - heap.first_free = hdr; - } - - if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 ) - mbedtls_exit( 1 ); -} - -void mbedtls_memory_buffer_set_verify( int verify ) -{ - heap.verify = verify; -} - -int mbedtls_memory_buffer_alloc_verify( void ) -{ - return verify_chain(); -} - -#if defined(MBEDTLS_MEMORY_DEBUG) -void mbedtls_memory_buffer_alloc_status( void ) -{ - mbedtls_fprintf( stderr, - "Current use: %zu blocks / %zu bytes, max: %zu blocks / " - "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n", - heap.header_count, heap.total_used, - heap.maximum_header_count, heap.maximum_used, - heap.maximum_header_count * sizeof( memory_header ) - + heap.maximum_used, - heap.alloc_count, heap.free_count ); - - if( heap.first->next == NULL ) - { - mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); - } - else - { - mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); - debug_chain(); - } -} - -void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ) -{ - *max_used = heap.maximum_used; - *max_blocks = heap.maximum_header_count; -} - -void mbedtls_memory_buffer_alloc_max_reset( void ) -{ - heap.maximum_used = 0; - heap.maximum_header_count = 0; -} - -void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ) -{ - *cur_used = heap.total_used; - *cur_blocks = heap.header_count; -} -#endif /* MBEDTLS_MEMORY_DEBUG */ - -#if defined(MBEDTLS_THREADING_C) -static void *buffer_alloc_calloc_mutexed( size_t n, size_t size ) -{ - void *buf; - if( mbedtls_mutex_lock( &heap.mutex ) != 0 ) - return( NULL ); - buf = buffer_alloc_calloc( n, size ); - if( mbedtls_mutex_unlock( &heap.mutex ) ) - return( NULL ); - return( buf ); -} - -static void buffer_alloc_free_mutexed( void *ptr ) -{ - /* We have to good option here, but corrupting the heap seems - * worse than loosing memory. */ - if( mbedtls_mutex_lock( &heap.mutex ) ) - return; - buffer_alloc_free( ptr ); - (void) mbedtls_mutex_unlock( &heap.mutex ); -} -#endif /* MBEDTLS_THREADING_C */ - -void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) -{ - memset( &heap, 0, sizeof( buffer_alloc_ctx ) ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &heap.mutex ); - mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed, - buffer_alloc_free_mutexed ); -#else - mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); -#endif - - if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - return; - else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - { - /* Adjust len first since buf is used in the computation */ - len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - } - - memset( buf, 0, len ); - - heap.buf = buf; - heap.len = len; - - heap.first = (memory_header *)buf; - heap.first->size = len - sizeof( memory_header ); - heap.first->magic1 = MAGIC1; - heap.first->magic2 = MAGIC2; - heap.first_free = heap.first; -} - -void mbedtls_memory_buffer_alloc_free( void ) -{ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &heap.mutex ); -#endif - mbedtls_platform_zeroize( &heap, sizeof(buffer_alloc_ctx) ); -} - -#if defined(MBEDTLS_SELF_TEST) -static int check_pointer( void *p ) -{ - if( p == NULL ) - return( -1 ); - - if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 ) - return( -1 ); - - return( 0 ); -} - -static int check_all_free( void ) -{ - if( -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.total_used != 0 || -#endif - heap.first != heap.first_free || - (void *) heap.first != (void *) heap.buf ) - { - return( -1 ); - } - - return( 0 ); -} - -#define TEST_ASSERT( condition ) \ - if( ! (condition) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf( "failed\n" ); \ - \ - ret = 1; \ - goto cleanup; \ - } - -int mbedtls_memory_buffer_alloc_self_test( int verbose ) -{ - unsigned char buf[1024]; - unsigned char *p, *q, *r, *end; - int ret = 0; - - if( verbose != 0 ) - mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " ); - - mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); - - p = mbedtls_calloc( 1, 1 ); - q = mbedtls_calloc( 1, 128 ); - r = mbedtls_calloc( 1, 16 ); - - TEST_ASSERT( check_pointer( p ) == 0 && - check_pointer( q ) == 0 && - check_pointer( r ) == 0 ); - - mbedtls_free( r ); - mbedtls_free( q ); - mbedtls_free( p ); - - TEST_ASSERT( check_all_free( ) == 0 ); - - /* Memorize end to compare with the next test */ - end = heap.buf + heap.len; - - mbedtls_memory_buffer_alloc_free( ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " MBA test #2 (buf not aligned): " ); - - mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 ); - - TEST_ASSERT( heap.buf + heap.len == end ); - - p = mbedtls_calloc( 1, 1 ); - q = mbedtls_calloc( 1, 128 ); - r = mbedtls_calloc( 1, 16 ); - - TEST_ASSERT( check_pointer( p ) == 0 && - check_pointer( q ) == 0 && - check_pointer( r ) == 0 ); - - mbedtls_free( r ); - mbedtls_free( q ); - mbedtls_free( p ); - - TEST_ASSERT( check_all_free( ) == 0 ); - - mbedtls_memory_buffer_alloc_free( ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " MBA test #3 (full): " ); - - mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); - - p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) ); - - TEST_ASSERT( check_pointer( p ) == 0 ); - TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); - - mbedtls_free( p ); - - p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 ); - q = mbedtls_calloc( 1, 16 ); - - TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 ); - TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); - - mbedtls_free( q ); - - TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL ); - - mbedtls_free( p ); - - TEST_ASSERT( check_all_free( ) == 0 ); - - mbedtls_memory_buffer_alloc_free( ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -cleanup: - mbedtls_memory_buffer_alloc_free( ); - - return( ret ); -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ diff --git a/library/nist_kw.c b/library/nist_kw.c deleted file mode 100644 index 317a2426ae..0000000000 --- a/library/nist_kw.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - * Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes - * only - * - * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ -/* - * Definition of Key Wrapping: - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf - * RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm" - * RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm" - * - * Note: RFC 3394 defines different methodology for intermediate operations for - * the wrapping and unwrapping operation than the definition in NIST SP 800-38F. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_NIST_KW_C) - -#include "mbedtls/nist_kw.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#if !defined(MBEDTLS_NIST_KW_ALT) - -#define KW_SEMIBLOCK_LENGTH 8 -#define MIN_SEMIBLOCKS_COUNT 3 - -/* constant-time buffer comparison */ -static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - volatile unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - { - /* Read volatile data in order before computing diff. - * This avoids IAR compiler warning: - * 'the order of volatile accesses is undefined ..' */ - unsigned char x = A[i], y = B[i]; - diff |= x ^ y; - } - - return( diff ); -} - -/*! The 64-bit default integrity check value (ICV) for KW mode. */ -static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}; -/*! The 32-bit default integrity check value (ICV) for KWP mode. */ -static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6}; - -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -do { \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} while( 0 ) -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -do { \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} while( 0 ) -#endif - -/* - * Initialize context - */ -void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_nist_kw_context ) ); -} - -int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits, - const int is_wrap ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - cipher_info = mbedtls_cipher_info_from_values( cipher, - keybits, - MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* - * SP 800-38F currently defines AES cipher as the only block cipher allowed: - * "For KW and KWP, the underlying block cipher shall be approved, and the - * block size shall be 128 bits. Currently, the AES block cipher, with key - * lengths of 128, 192, or 256 bits, is the only block cipher that fits - * this profile." - * Currently we don't support other 128 bit block ciphers for key wrapping, - * such as Camellia and Aria. - */ - if( cipher != MBEDTLS_CIPHER_ID_AES ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - is_wrap ? MBEDTLS_ENCRYPT : - MBEDTLS_DECRYPT ) - ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Free context - */ -void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ) -{ - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_nist_kw_context ) ); -} - -/* - * Helper function for Xoring the uint64_t "t" with the encrypted A. - * Defined in NIST SP 800-38F section 6.1 - */ -static void calc_a_xor_t( unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t ) -{ - size_t i = 0; - for( i = 0; i < sizeof( t ); i++ ) - { - A[i] ^= ( t >> ( ( sizeof( t ) - 1 - i ) * 8 ) ) & 0xff; - } -} - -/* - * KW-AE as defined in SP 800-38F section 6.2 - * KWP-AE as defined in SP 800-38F section 6.3 - */ -int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, - mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size ) -{ - int ret = 0; - size_t semiblocks = 0; - size_t s; - size_t olen, padlen = 0; - uint64_t t = 0; - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH; - unsigned char *A = output; - - *out_len = 0; - /* - * Generate the String to work on - */ - if( mode == MBEDTLS_KW_MODE_KW ) - { - if( out_size < in_len + KW_SEMIBLOCK_LENGTH ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - /* - * According to SP 800-38F Table 1, the plaintext length for KW - * must be between 2 to 2^54-1 semiblocks inclusive. - */ - if( in_len < 16 || -#if SIZE_MAX > 0x1FFFFFFFFFFFFF8 - in_len > 0x1FFFFFFFFFFFFF8 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH ); - memmove( output + KW_SEMIBLOCK_LENGTH, input, in_len ); - } - else - { - if( in_len % 8 != 0 ) - { - padlen = ( 8 - ( in_len % 8 ) ); - } - - if( out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - /* - * According to SP 800-38F Table 1, the plaintext length for KWP - * must be between 1 and 2^32-1 octets inclusive. - */ - if( in_len < 1 -#if SIZE_MAX > 0xFFFFFFFF - || in_len > 0xFFFFFFFF -#endif - ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 ); - PUT_UINT32_BE( ( in_len & 0xffffffff ), output, - KW_SEMIBLOCK_LENGTH / 2 ); - - memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len ); - memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen ); - } - semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1; - - s = 6 * ( semiblocks - 1 ); - - if( mode == MBEDTLS_KW_MODE_KWP - && in_len <= KW_SEMIBLOCK_LENGTH ) - { - memcpy( inbuff, output, 16 ); - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - inbuff, 16, output, &olen ); - if( ret != 0 ) - goto cleanup; - } - else - { - /* - * Do the wrapping function W, as defined in RFC 3394 section 2.2.1 - */ - if( semiblocks < MIN_SEMIBLOCKS_COUNT ) - { - ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - goto cleanup; - } - - /* Calculate intermediate values */ - for( t = 1; t <= s; t++ ) - { - memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); - memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH ); - - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - inbuff, 16, outbuff, &olen ); - if( ret != 0 ) - goto cleanup; - - memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); - calc_a_xor_t( A, t ); - - memcpy( R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); - R2 += KW_SEMIBLOCK_LENGTH; - if( R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) ) - R2 = output + KW_SEMIBLOCK_LENGTH; - } - } - - *out_len = semiblocks * KW_SEMIBLOCK_LENGTH; - -cleanup: - - if( ret != 0) - { - memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH ); - } - mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 ); - mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 ); - - return( ret ); -} - -/* - * W-1 function as defined in RFC 3394 section 2.2.2 - * This function assumes the following: - * 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH. - * 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH. - * 3. Minimal number of semiblocks is 3. - * 4. A is a buffer to hold the first semiblock of the input buffer. - */ -static int unwrap( mbedtls_nist_kw_context *ctx, - const unsigned char *input, size_t semiblocks, - unsigned char A[KW_SEMIBLOCK_LENGTH], - unsigned char *output, size_t* out_len ) -{ - int ret = 0; - const size_t s = 6 * ( semiblocks - 1 ); - size_t olen; - uint64_t t = 0; - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; - *out_len = 0; - - if( semiblocks < MIN_SEMIBLOCKS_COUNT ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - memcpy( A, input, KW_SEMIBLOCK_LENGTH ); - memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); - - /* Calculate intermediate values */ - for( t = s; t >= 1; t-- ) - { - calc_a_xor_t( A, t ); - - memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); - memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH ); - - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - inbuff, 16, outbuff, &olen ); - if( ret != 0 ) - goto cleanup; - - memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); - - /* Set R as LSB64 of outbuff */ - memcpy( R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); - - if( R == output ) - R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; - else - R -= KW_SEMIBLOCK_LENGTH; - } - - *out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH; - -cleanup: - if( ret != 0) - memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); - mbedtls_platform_zeroize( inbuff, sizeof( inbuff ) ); - mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); - - return( ret ); -} - -/* - * KW-AD as defined in SP 800-38F section 6.2 - * KWP-AD as defined in SP 800-38F section 6.3 - */ -int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, - mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size ) -{ - int ret = 0; - size_t i, olen; - unsigned char A[KW_SEMIBLOCK_LENGTH]; - unsigned char diff, bad_padding = 0; - - *out_len = 0; - if( out_size < in_len - KW_SEMIBLOCK_LENGTH ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - if( mode == MBEDTLS_KW_MODE_KW ) - { - /* - * According to SP 800-38F Table 1, the ciphertext length for KW - * must be between 3 to 2^54 semiblocks inclusive. - */ - if( in_len < 24 || -#if SIZE_MAX > 0x200000000000000 - in_len > 0x200000000000000 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, - A, output, out_len ); - if( ret != 0 ) - goto cleanup; - - /* Check ICV in "constant-time" */ - diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH ); - - if( diff != 0 ) - { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - goto cleanup; - } - - } - else if( mode == MBEDTLS_KW_MODE_KWP ) - { - size_t padlen = 0; - uint32_t Plen; - /* - * According to SP 800-38F Table 1, the ciphertext length for KWP - * must be between 2 to 2^29 semiblocks inclusive. - */ - if( in_len < KW_SEMIBLOCK_LENGTH * 2 || -#if SIZE_MAX > 0x100000000 - in_len > 0x100000000 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - if( in_len == KW_SEMIBLOCK_LENGTH * 2 ) - { - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - input, 16, outbuff, &olen ); - if( ret != 0 ) - goto cleanup; - - memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); - memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); - mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); - *out_len = KW_SEMIBLOCK_LENGTH; - } - else - { - /* in_len >= KW_SEMIBLOCK_LENGTH * 3 */ - ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, - A, output, out_len ); - if( ret != 0 ) - goto cleanup; - } - - /* Check ICV in "constant-time" */ - diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 ); - - if( diff != 0 ) - { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 ); - - /* - * Plen is the length of the plaintext, when the input is valid. - * If Plen is larger than the plaintext and padding, padlen will be - * larger than 8, because of the type wrap around. - */ - padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen; - if ( padlen > 7 ) - { - padlen &= 7; - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - /* Check padding in "constant-time" */ - for( diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++ ) - { - if( i >= KW_SEMIBLOCK_LENGTH - padlen ) - diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; - else - bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; - } - - if( diff != 0 ) - { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - if( ret != 0 ) - { - goto cleanup; - } - memset( output + Plen, 0, padlen ); - *out_len = Plen; - } - else - { - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto cleanup; - } - -cleanup: - if( ret != 0 ) - { - memset( output, 0, *out_len ); - *out_len = 0; - } - - mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) ); - mbedtls_platform_zeroize( &diff, sizeof( diff ) ); - mbedtls_platform_zeroize( A, sizeof( A ) ); - - return( ret ); -} - -#endif /* !MBEDTLS_NIST_KW_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) - -#define KW_TESTS 3 - -/* - * Test vectors taken from NIST - * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW - */ -static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 }; - -static const unsigned char kw_key[KW_TESTS][32] = { - { 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2, - 0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 }, - { 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b, - 0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d, - 0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 }, - { 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25, - 0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33, - 0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d, - 0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 } -}; - -static const unsigned char kw_msg[KW_TESTS][40] = { - { 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea, - 0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f }, - { 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb, - 0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d, - 0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45, - 0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d, - 0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c }, - { 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7, - 0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8, - 0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 } -}; - -static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 }; -static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 }; -static const unsigned char kw_res[KW_TESTS][48] = { - { 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d, - 0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3, - 0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb }, - { 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91, - 0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec, - 0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d, - 0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8, - 0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19, - 0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d }, - { 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d, - 0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87, - 0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9, - 0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 } -}; - -static const unsigned char kwp_key[KW_TESTS][32] = { - { 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a, - 0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 }, - { 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98, - 0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7, - 0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 }, - { 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5, - 0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f, - 0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae, - 0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a } -}; - -static const unsigned char kwp_msg[KW_TESTS][31] = { - { 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8, - 0x96 }, - { 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb, - 0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19, - 0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66, - 0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f }, - { 0xd1 } -}; -static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 }; - -static const unsigned char kwp_res[KW_TESTS][48] = { - { 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e, - 0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7, - 0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 }, - { 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13, - 0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88, - 0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63, - 0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90, - 0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 }, - { 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd, - 0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 } -}; -static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 }; - -int mbedtls_nist_kw_self_test( int verbose ) -{ - mbedtls_nist_kw_context ctx; - unsigned char out[48]; - size_t olen; - int i; - int ret = 0; - mbedtls_nist_kw_init( &ctx ); - - for( i = 0; i < KW_TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " KW-AES-%u ", (unsigned int) key_len[i] * 8 ); - - ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, - kw_key[i], key_len[i] * 8, 1 ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KW: setup failed " ); - - goto end; - } - - ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KW, kw_msg[i], - kw_msg_len[i], out, &olen, sizeof( out ) ); - if( ret != 0 || kw_out_len[i] != olen || - memcmp( out, kw_res[i], kw_out_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed. "); - - ret = 1; - goto end; - } - - if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, - kw_key[i], key_len[i] * 8, 0 ) ) - != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KW: setup failed "); - - goto end; - } - - ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KW, - out, olen, out, &olen, sizeof( out ) ); - - if( ret != 0 || olen != kw_msg_len[i] || - memcmp( out, kw_msg[i], kw_msg_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto end; - } - - if( verbose != 0 ) - mbedtls_printf( " passed\n" ); - } - - for( i = 0; i < KW_TESTS; i++ ) - { - olen = sizeof( out ); - if( verbose != 0 ) - mbedtls_printf( " KWP-AES-%u ", (unsigned int) key_len[i] * 8 ); - - ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i], - key_len[i] * 8, 1 ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KWP: setup failed " ); - - goto end; - } - ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i], - kwp_msg_len[i], out, &olen, sizeof( out ) ); - - if( ret != 0 || kwp_out_len[i] != olen || - memcmp( out, kwp_res[i], kwp_out_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed. "); - - ret = 1; - goto end; - } - - if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, - kwp_key[i], key_len[i] * 8, 0 ) ) - != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KWP: setup failed "); - - goto end; - } - - ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KWP, out, - olen, out, &olen, sizeof( out ) ); - - if( ret != 0 || olen != kwp_msg_len[i] || - memcmp( out, kwp_msg[i], kwp_msg_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed. "); - - ret = 1; - goto end; - } - - if( verbose != 0 ) - mbedtls_printf( " passed\n" ); - } -end: - mbedtls_nist_kw_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_NIST_KW_C */ diff --git a/library/oid.c b/library/oid.c deleted file mode 100644 index 27c455e877..0000000000 --- a/library/oid.c +++ /dev/null @@ -1,772 +0,0 @@ -/** - * \file oid.c - * - * \brief Object Identifier (OID) database - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_OID_C) - -#include "mbedtls/oid.h" -#include "mbedtls/rsa.h" - -#include -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_snprintf snprintf -#endif - -/* - * Macro to automatically add the size of #define'd OIDs - */ -#define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s) - -/* - * Macro to generate an internal function for oid_XXX_from_asn1() (used by - * the other functions) - */ -#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ - static const TYPE_T * oid_ ## NAME ## _from_asn1( \ - const mbedtls_asn1_buf *oid ) \ - { \ - const TYPE_T *p = (LIST); \ - const mbedtls_oid_descriptor_t *cur = \ - (const mbedtls_oid_descriptor_t *) p; \ - if( p == NULL || oid == NULL ) return( NULL ); \ - while( cur->asn1 != NULL ) { \ - if( cur->asn1_len == oid->len && \ - memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ - return( p ); \ - } \ - p++; \ - cur = (const mbedtls_oid_descriptor_t *) p; \ - } \ - return( NULL ); \ - } - -/* - * Macro to generate a function for retrieving a single attribute from the - * descriptor of an mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ -{ \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *ATTR1 = data->descriptor.ATTR1; \ - return( 0 ); \ -} - -/* - * Macro to generate a function for retrieving a single attribute from an - * mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ -{ \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *ATTR1 = data->ATTR1; \ - return( 0 ); \ -} - -/* - * Macro to generate a function for retrieving two attributes from an - * mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ - ATTR2_TYPE, ATTR2) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \ - ATTR2_TYPE * ATTR2 ) \ -{ \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *(ATTR1) = data->ATTR1; \ - *(ATTR2) = data->ATTR2; \ - return( 0 ); \ -} - -/* - * Macro to generate a function for retrieving the OID based on a single - * attribute from a mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ -int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ -{ \ - const TYPE_T *cur = (LIST); \ - while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == (ATTR1) ) { \ - *oid = cur->descriptor.asn1; \ - *olen = cur->descriptor.asn1_len; \ - return( 0 ); \ - } \ - cur++; \ - } \ - return( MBEDTLS_ERR_OID_NOT_FOUND ); \ -} - -/* - * Macro to generate a function for retrieving the OID based on two - * attributes from a mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \ - ATTR2_TYPE, ATTR2) \ -int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ - size_t *olen ) \ -{ \ - const TYPE_T *cur = (LIST); \ - while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2) ) { \ - *oid = cur->descriptor.asn1; \ - *olen = cur->descriptor.asn1_len; \ - return( 0 ); \ - } \ - cur++; \ - } \ - return( MBEDTLS_ERR_OID_NOT_FOUND ); \ -} - -/* - * For X520 attribute types - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - const char *short_name; -} oid_x520_attr_t; - -static const oid_x520_attr_t oid_x520_attr_type[] = -{ - { - { ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" }, - "CN", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" }, - "C", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" }, - "L", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" }, - "ST", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" }, - "O", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" }, - "OU", - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" }, - "emailAddress", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" }, - "serialNumber", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" }, - "postalAddress", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, - "postalCode", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, - "SN", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, - "GN", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" }, - "initials", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, - "generationQualifier", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" }, - "title", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, - "dnQualifier", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, - "pseudonym", - }, - { - { ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, - "DC", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" }, - "uniqueIdentifier", - }, - { - { NULL, 0, NULL, NULL }, - NULL, - } -}; - -FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) -FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name) - -/* - * For X509 extensions - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - int ext_type; -} oid_x509_ext_t; - -static const oid_x509_ext_t oid_x509_ext[] = -{ - { - { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, - MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS, - }, - { - { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" }, - MBEDTLS_OID_X509_EXT_KEY_USAGE, - }, - { - { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" }, - MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE, - }, - { - { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" }, - MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME, - }, - { - { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" }, - MBEDTLS_OID_X509_EXT_NS_CERT_TYPE, - }, - { - { ADD_LEN( MBEDTLS_OID_CERTIFICATE_POLICIES ), "id-ce-certificatePolicies", "Certificate Policies" }, - MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES, - }, - { - { NULL, 0, NULL, NULL }, - 0, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext) -FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type) - -static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = -{ - { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, - { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, - { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" }, - { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" }, - { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" }, - { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" }, - { ADD_LEN( MBEDTLS_OID_WISUN_FAN ), "id-kp-wisun-fan-device", "Wi-SUN Alliance Field Area Network (FAN)" }, - { NULL, 0, NULL, NULL }, -}; - -FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage) -FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description) - -static const mbedtls_oid_descriptor_t oid_certificate_policies[] = -{ - { ADD_LEN( MBEDTLS_OID_ANY_POLICY ), "anyPolicy", "Any Policy" }, - { NULL, 0, NULL, NULL }, -}; - -FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, certificate_policies, oid_certificate_policies) -FN_OID_GET_ATTR1(mbedtls_oid_get_certificate_policies, mbedtls_oid_descriptor_t, certificate_policies, const char *, description) - -#if defined(MBEDTLS_MD_C) -/* - * For SignatureAlgorithmIdentifier - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; - mbedtls_pk_type_t pk_alg; -} oid_sig_alg_t; - -static const oid_sig_alg_t oid_sig_alg[] = -{ -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_MD2_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, - MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD2_C */ -#if defined(MBEDTLS_MD4_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, - MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD4_C */ -#if defined(MBEDTLS_MD5_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, - MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD5_C */ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, - MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, - MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, - MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, - MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, - MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, - MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, - MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, - MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, - }, - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, - MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, - MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, - }, - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, - MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_ECDSA_C */ -#if defined(MBEDTLS_RSA_C) - { - { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, - MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, - }, -#endif /* MBEDTLS_RSA_C */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg) -FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description) -FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg) -FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg) -#endif /* MBEDTLS_MD_C */ - -/* - * For PublicKeyInfo (PKCS1, RFC 5480) - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_pk_type_t pk_alg; -} oid_pk_alg_t; - -static const oid_pk_alg_t oid_pk_alg[] = -{ - { - { ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, - MBEDTLS_PK_RSA, - }, - { - { ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" }, - MBEDTLS_PK_ECKEY, - }, - { - { ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" }, - MBEDTLS_PK_ECKEY_DH, - }, - { - { NULL, 0, NULL, NULL }, - MBEDTLS_PK_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg) - -#if defined(MBEDTLS_ECP_C) -/* - * For namedCurve (RFC 5480) - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_ecp_group_id grp_id; -} oid_ecp_grp_t; - -static const oid_ecp_grp_t oid_ecp_grp[] = -{ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, - MBEDTLS_ECP_DP_SECP192R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, - MBEDTLS_ECP_DP_SECP224R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, - MBEDTLS_ECP_DP_SECP256R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, - MBEDTLS_ECP_DP_SECP384R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, - MBEDTLS_ECP_DP_SECP521R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, - MBEDTLS_ECP_DP_SECP192K1, - }, -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, - MBEDTLS_ECP_DP_SECP224K1, - }, -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, - MBEDTLS_ECP_DP_SECP256K1, - }, -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, - MBEDTLS_ECP_DP_BP256R1, - }, -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, - MBEDTLS_ECP_DP_BP384R1, - }, -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, - MBEDTLS_ECP_DP_BP512R1, - }, -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_ECP_DP_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp) -FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id) -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_CIPHER_C) -/* - * For PKCS#5 PBES2 encryption algorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_cipher_type_t cipher_alg; -} oid_cipher_alg_t; - -static const oid_cipher_alg_t oid_cipher_alg[] = -{ - { - { ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" }, - MBEDTLS_CIPHER_DES_CBC, - }, - { - { ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" }, - MBEDTLS_CIPHER_DES_EDE3_CBC, - }, - { - { NULL, 0, NULL, NULL }, - MBEDTLS_CIPHER_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, mbedtls_cipher_type_t, cipher_alg) -#endif /* MBEDTLS_CIPHER_C */ - -#if defined(MBEDTLS_MD_C) -/* - * For digestAlgorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; -} oid_md_alg_t; - -static const oid_md_alg_t oid_md_alg[] = -{ -#if defined(MBEDTLS_MD2_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, - MBEDTLS_MD_MD2, - }, -#endif /* MBEDTLS_MD2_C */ -#if defined(MBEDTLS_MD4_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, - MBEDTLS_MD_MD4, - }, -#endif /* MBEDTLS_MD4_C */ -#if defined(MBEDTLS_MD5_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, - MBEDTLS_MD_MD5, - }, -#endif /* MBEDTLS_MD5_C */ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, - MBEDTLS_MD_SHA1, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, - MBEDTLS_MD_SHA224, - }, - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, - MBEDTLS_MD_SHA256, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, - MBEDTLS_MD_SHA384, - }, - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, - MBEDTLS_MD_SHA512, - }, -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_RIPEMD160_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_RIPEMD160 ), "id-ripemd160", "RIPEMD-160" }, - MBEDTLS_MD_RIPEMD160, - }, -#endif /* MBEDTLS_RIPEMD160_C */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg) - -/* - * For HMAC digestAlgorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_hmac; -} oid_md_hmac_t; - -static const oid_md_hmac_t oid_md_hmac[] = -{ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" }, - MBEDTLS_MD_SHA1, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" }, - MBEDTLS_MD_SHA224, - }, - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" }, - MBEDTLS_MD_SHA256, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" }, - MBEDTLS_MD_SHA384, - }, - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" }, - MBEDTLS_MD_SHA512, - }, -#endif /* MBEDTLS_SHA512_C */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac) -FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac) -#endif /* MBEDTLS_MD_C */ - -#if defined(MBEDTLS_PKCS12_C) -/* - * For PKCS#12 PBEs - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; - mbedtls_cipher_type_t cipher_alg; -} oid_pkcs12_pbe_alg_t; - -static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = -{ - { - { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, - MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC, - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" }, - MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC, - }, - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg) -FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, mbedtls_md_type_t, md_alg, mbedtls_cipher_type_t, cipher_alg) -#endif /* MBEDTLS_PKCS12_C */ - -#define OID_SAFE_SNPRINTF \ - do { \ - if( ret < 0 || (size_t) ret >= n ) \ - return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); \ - \ - n -= (size_t) ret; \ - p += (size_t) ret; \ - } while( 0 ) - -/* Return the x.y.z.... style numeric string for the given OID */ -int mbedtls_oid_get_numeric_string( char *buf, size_t size, - const mbedtls_asn1_buf *oid ) -{ - int ret; - size_t i, n; - unsigned int value; - char *p; - - p = buf; - n = size; - - /* First byte contains first two dots */ - if( oid->len > 0 ) - { - ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 ); - OID_SAFE_SNPRINTF; - } - - value = 0; - for( i = 1; i < oid->len; i++ ) - { - /* Prevent overflow in value. */ - if( ( ( value << 7 ) >> 7 ) != value ) - return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); - - value <<= 7; - value += oid->p[i] & 0x7F; - - if( !( oid->p[i] & 0x80 ) ) - { - /* Last byte */ - ret = mbedtls_snprintf( p, n, ".%d", value ); - OID_SAFE_SNPRINTF; - value = 0; - } - } - - return( (int) ( size - n ) ); -} - -#endif /* MBEDTLS_OID_C */ diff --git a/library/padlock.c b/library/padlock.c deleted file mode 100644 index b85ff9cd2c..0000000000 --- a/library/padlock.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * VIA PadLock support functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * This implementation is based on the VIA PadLock Programming Guide: - * - * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ - * programming_guide.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PADLOCK_C) - -#include "mbedtls/padlock.h" - -#include - -#ifndef asm -#define asm __asm -#endif - -#if defined(MBEDTLS_HAVE_X86) - -/* - * PadLock detection routine - */ -int mbedtls_padlock_has_support( int feature ) -{ - static int flags = -1; - int ebx = 0, edx = 0; - - if( flags == -1 ) - { - asm( "movl %%ebx, %0 \n\t" - "movl $0xC0000000, %%eax \n\t" - "cpuid \n\t" - "cmpl $0xC0000001, %%eax \n\t" - "movl $0, %%edx \n\t" - "jb unsupported \n\t" - "movl $0xC0000001, %%eax \n\t" - "cpuid \n\t" - "unsupported: \n\t" - "movl %%edx, %1 \n\t" - "movl %2, %%ebx \n\t" - : "=m" (ebx), "=m" (edx) - : "m" (ebx) - : "eax", "ecx", "edx" ); - - flags = edx; - } - - return( flags & feature ); -} - -/* - * PadLock AES-ECB block en(de)cryption - */ -int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - int ebx = 0; - uint32_t *rk; - uint32_t *blk; - uint32_t *ctrl; - unsigned char buf[256]; - - rk = ctx->rk; - blk = MBEDTLS_PADLOCK_ALIGN16( buf ); - memcpy( blk, input, 16 ); - - ctrl = blk + 4; - *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); - - asm( "pushfl \n\t" - "popfl \n\t" - "movl %%ebx, %0 \n\t" - "movl $1, %%ecx \n\t" - "movl %2, %%edx \n\t" - "movl %3, %%ebx \n\t" - "movl %4, %%esi \n\t" - "movl %4, %%edi \n\t" - ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" - "movl %1, %%ebx \n\t" - : "=m" (ebx) - : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) - : "memory", "ecx", "edx", "esi", "edi" ); - - memcpy( output, blk, 16 ); - - return( 0 ); -} - -/* - * PadLock AES-CBC buffer en(de)cryption - */ -int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int ebx = 0; - size_t count; - uint32_t *rk; - uint32_t *iw; - uint32_t *ctrl; - unsigned char buf[256]; - - if( ( (long) input & 15 ) != 0 || - ( (long) output & 15 ) != 0 ) - return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED ); - - rk = ctx->rk; - iw = MBEDTLS_PADLOCK_ALIGN16( buf ); - memcpy( iw, iv, 16 ); - - ctrl = iw + 4; - *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); - - count = ( length + 15 ) >> 4; - - asm( "pushfl \n\t" - "popfl \n\t" - "movl %%ebx, %0 \n\t" - "movl %2, %%ecx \n\t" - "movl %3, %%edx \n\t" - "movl %4, %%ebx \n\t" - "movl %5, %%esi \n\t" - "movl %6, %%edi \n\t" - "movl %7, %%eax \n\t" - ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" - "movl %1, %%ebx \n\t" - : "=m" (ebx) - : "m" (ebx), "m" (count), "m" (ctrl), - "m" (rk), "m" (input), "m" (output), "m" (iw) - : "memory", "eax", "ecx", "edx", "esi", "edi" ); - - memcpy( iv, iw, 16 ); - - return( 0 ); -} - -#endif /* MBEDTLS_HAVE_X86 */ - -#endif /* MBEDTLS_PADLOCK_C */ diff --git a/library/pem.c b/library/pem.c deleted file mode 100644 index 897c8a0d6f..0000000000 --- a/library/pem.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Privacy Enhanced Mail (PEM) decoding - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) - -#include "mbedtls/pem.h" -#include "mbedtls/base64.h" -#include "mbedtls/des.h" -#include "mbedtls/aes.h" -#include "mbedtls/md5.h" -#include "mbedtls/cipher.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) -void mbedtls_pem_init( mbedtls_pem_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_pem_context ) ); -} - -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) -/* - * Read a 16-byte hex string and convert it to binary - */ -static int pem_get_iv( const unsigned char *s, unsigned char *iv, - size_t iv_len ) -{ - size_t i, j, k; - - memset( iv, 0, iv_len ); - - for( i = 0; i < iv_len * 2; i++, s++ ) - { - if( *s >= '0' && *s <= '9' ) j = *s - '0'; else - if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else - if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - k = ( ( i & 1 ) != 0 ) ? j : j << 4; - - iv[i >> 1] = (unsigned char)( iv[i >> 1] | k ); - } - - return( 0 ); -} - -static int pem_pbkdf1( unsigned char *key, size_t keylen, - unsigned char *iv, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_md5_context md5_ctx; - unsigned char md5sum[16]; - size_t use_len; - int ret; - - mbedtls_md5_init( &md5_ctx ); - - /* - * key[ 0..15] = MD5(pwd || IV) - */ - if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 ) - goto exit; - - if( keylen <= 16 ) - { - memcpy( key, md5sum, keylen ); - goto exit; - } - - memcpy( key, md5sum, 16 ); - - /* - * key[16..23] = MD5(key[ 0..15] || pwd || IV]) - */ - if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 ) - goto exit; - - use_len = 16; - if( keylen < 32 ) - use_len = keylen - 16; - - memcpy( key + 16, md5sum, use_len ); - -exit: - mbedtls_md5_free( &md5_ctx ); - mbedtls_platform_zeroize( md5sum, 16 ); - - return( ret ); -} - -#if defined(MBEDTLS_DES_C) -/* - * Decrypt with DES-CBC, using PBKDF1 for key derivation - */ -static int pem_des_decrypt( unsigned char des_iv[8], - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_des_context des_ctx; - unsigned char des_key[8]; - int ret; - - mbedtls_des_init( &des_ctx ); - - if( ( ret = pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 ) - goto exit; - ret = mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen, - des_iv, buf, buf ); - -exit: - mbedtls_des_free( &des_ctx ); - mbedtls_platform_zeroize( des_key, 8 ); - - return( ret ); -} - -/* - * Decrypt with 3DES-CBC, using PBKDF1 for key derivation - */ -static int pem_des3_decrypt( unsigned char des3_iv[8], - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_des3_context des3_ctx; - unsigned char des3_key[24]; - int ret; - - mbedtls_des3_init( &des3_ctx ); - - if( ( ret = pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 ) - goto exit; - ret = mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen, - des3_iv, buf, buf ); - -exit: - mbedtls_des3_free( &des3_ctx ); - mbedtls_platform_zeroize( des3_key, 24 ); - - return( ret ); -} -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* - * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation - */ -static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_aes_context aes_ctx; - unsigned char aes_key[32]; - int ret; - - mbedtls_aes_init( &aes_ctx ); - - if( ( ret = pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 ) - goto exit; - ret = mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen, - aes_iv, buf, buf ); - -exit: - mbedtls_aes_free( &aes_ctx ); - mbedtls_platform_zeroize( aes_key, keylen ); - - return( ret ); -} -#endif /* MBEDTLS_AES_C */ - -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - -int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer, - const unsigned char *data, const unsigned char *pwd, - size_t pwdlen, size_t *use_len ) -{ - int ret, enc; - size_t len; - unsigned char *buf; - const unsigned char *s1, *s2, *end; -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) - unsigned char pem_iv[16]; - mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE; -#else - ((void) pwd); - ((void) pwdlen); -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - - if( ctx == NULL ) - return( MBEDTLS_ERR_PEM_BAD_INPUT_DATA ); - - s1 = (unsigned char *) strstr( (const char *) data, header ); - - if( s1 == NULL ) - return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); - - s2 = (unsigned char *) strstr( (const char *) data, footer ); - - if( s2 == NULL || s2 <= s1 ) - return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); - - s1 += strlen( header ); - if( *s1 == ' ' ) s1++; - if( *s1 == '\r' ) s1++; - if( *s1 == '\n' ) s1++; - else return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); - - end = s2; - end += strlen( footer ); - if( *end == ' ' ) end++; - if( *end == '\r' ) end++; - if( *end == '\n' ) end++; - *use_len = end - data; - - enc = 0; - - if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) - { -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) - enc++; - - s1 += 22; - if( *s1 == '\r' ) s1++; - if( *s1 == '\n' ) s1++; - else return( MBEDTLS_ERR_PEM_INVALID_DATA ); - - -#if defined(MBEDTLS_DES_C) - if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) - { - enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; - - s1 += 23; - if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 ) - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - s1 += 16; - } - else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) - { - enc_alg = MBEDTLS_CIPHER_DES_CBC; - - s1 += 18; - if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 ) - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - s1 += 16; - } -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) - { - if( s2 - s1 < 22 ) - return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); - else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) - enc_alg = MBEDTLS_CIPHER_AES_128_CBC; - else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) - enc_alg = MBEDTLS_CIPHER_AES_192_CBC; - else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) - enc_alg = MBEDTLS_CIPHER_AES_256_CBC; - else - return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); - - s1 += 22; - if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 ) - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - s1 += 32; - } -#endif /* MBEDTLS_AES_C */ - - if( enc_alg == MBEDTLS_CIPHER_NONE ) - return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); - - if( *s1 == '\r' ) s1++; - if( *s1 == '\n' ) s1++; - else return( MBEDTLS_ERR_PEM_INVALID_DATA ); -#else - return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - } - - if( s1 >= s2 ) - return( MBEDTLS_ERR_PEM_INVALID_DATA ); - - ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); - - if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER ) - return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); - - if( ( buf = mbedtls_calloc( 1, len ) ) == NULL ) - return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); - - if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 ) - { - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); - } - - if( enc != 0 ) - { -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) - if( pwd == NULL ) - { - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ); - } - - ret = 0; - -#if defined(MBEDTLS_DES_C) - if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC ) - ret = pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen ); - else if( enc_alg == MBEDTLS_CIPHER_DES_CBC ) - ret = pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen ); -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC ) - ret = pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen ); - else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC ) - ret = pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen ); - else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC ) - ret = pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen ); -#endif /* MBEDTLS_AES_C */ - - if( ret != 0 ) - { - mbedtls_free( buf ); - return( ret ); - } - - /* - * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 - * length bytes (allow 4 to be sure) in all known use cases. - * - * Use that as a heuristic to try to detect password mismatches. - */ - if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) - { - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ); - } -#else - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - } - - ctx->buf = buf; - ctx->buflen = len; - - return( 0 ); -} - -void mbedtls_pem_free( mbedtls_pem_context *ctx ) -{ - if ( ctx->buf != NULL ) - { - mbedtls_platform_zeroize( ctx->buf, ctx->buflen ); - mbedtls_free( ctx->buf ); - } - mbedtls_free( ctx->info ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) ); -} -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_pem_write_buffer( const char *header, const char *footer, - const unsigned char *der_data, size_t der_len, - unsigned char *buf, size_t buf_len, size_t *olen ) -{ - int ret; - unsigned char *encode_buf = NULL, *c, *p = buf; - size_t len = 0, use_len, add_len = 0; - - mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len ); - add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; - - if( use_len + add_len > buf_len ) - { - *olen = use_len + add_len; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - if( use_len != 0 && - ( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) ) - return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); - - if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data, - der_len ) ) != 0 ) - { - mbedtls_free( encode_buf ); - return( ret ); - } - - memcpy( p, header, strlen( header ) ); - p += strlen( header ); - c = encode_buf; - - while( use_len ) - { - len = ( use_len > 64 ) ? 64 : use_len; - memcpy( p, c, len ); - use_len -= len; - p += len; - c += len; - *p++ = '\n'; - } - - memcpy( p, footer, strlen( footer ) ); - p += strlen( footer ); - - *p++ = '\0'; - *olen = p - buf; - - mbedtls_free( encode_buf ); - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ diff --git a/library/pk.c b/library/pk.c deleted file mode 100644 index a1e278e738..0000000000 --- a/library/pk.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Public Key abstraction layer - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk.h" -#include "mbedtls/pk_internal.h" - -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -#endif - -#include -#include - -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * Initialise a mbedtls_pk_context - */ -void mbedtls_pk_init( mbedtls_pk_context *ctx ) -{ - PK_VALIDATE( ctx != NULL ); - - ctx->pk_info = NULL; - ctx->pk_ctx = NULL; -} - -/* - * Free (the components of) a mbedtls_pk_context - */ -void mbedtls_pk_free( mbedtls_pk_context *ctx ) -{ - if( ctx == NULL ) - return; - - if ( ctx->pk_info != NULL ) - ctx->pk_info->ctx_free_func( ctx->pk_ctx ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) ); -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ) -{ - PK_VALIDATE( ctx != NULL ); - ctx->pk_info = NULL; - ctx->rs_ctx = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ) -{ - if( ctx == NULL || ctx->pk_info == NULL || - ctx->pk_info->rs_free_func == NULL ) - { - return; - } - - ctx->pk_info->rs_free_func( ctx->rs_ctx ); - - ctx->pk_info = NULL; - ctx->rs_ctx = NULL; -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* - * Get pk_info structure from type - */ -const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) -{ - switch( pk_type ) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_PK_RSA: - return( &mbedtls_rsa_info ); -#endif -#if defined(MBEDTLS_ECP_C) - case MBEDTLS_PK_ECKEY: - return( &mbedtls_eckey_info ); - case MBEDTLS_PK_ECKEY_DH: - return( &mbedtls_eckeydh_info ); -#endif -#if defined(MBEDTLS_ECDSA_C) - case MBEDTLS_PK_ECDSA: - return( &mbedtls_ecdsa_info ); -#endif - /* MBEDTLS_PK_RSA_ALT omitted on purpose */ - default: - return( NULL ); - } -} - -/* - * Initialise context - */ -int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) -{ - PK_VALIDATE_RET( ctx != NULL ); - if( info == NULL || ctx->pk_info != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - return( 0 ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* - * Initialise a PSA-wrapping context - */ -int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key ) -{ - const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info; - psa_key_handle_t *pk_ctx; - psa_key_type_t type; - - if( ctx == NULL || ctx->pk_info != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( PSA_SUCCESS != psa_get_key_information( key, &type, NULL ) ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* Current implementation of can_do() relies on this. */ - if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) ) - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ; - - if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - pk_ctx = (psa_key_handle_t *) ctx->pk_ctx; - *pk_ctx = key; - - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* - * Initialize an RSA-alt context - */ -int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, - mbedtls_pk_rsa_alt_decrypt_func decrypt_func, - mbedtls_pk_rsa_alt_sign_func sign_func, - mbedtls_pk_rsa_alt_key_len_func key_len_func ) -{ - mbedtls_rsa_alt_context *rsa_alt; - const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; - - PK_VALIDATE_RET( ctx != NULL ); - if( ctx->pk_info != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; - - rsa_alt->key = key; - rsa_alt->decrypt_func = decrypt_func; - rsa_alt->sign_func = sign_func; - rsa_alt->key_len_func = key_len_func; - - return( 0 ); -} -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/* - * Tell if a PK can do the operations of the given type - */ -int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) -{ - /* A context with null pk_info is not set up yet and can't do anything. - * For backward compatibility, also accept NULL instead of a context - * pointer. */ - if( ctx == NULL || ctx->pk_info == NULL ) - return( 0 ); - - return( ctx->pk_info->can_do( type ) ); -} - -/* - * Helper for mbedtls_pk_sign and mbedtls_pk_verify - */ -static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len ) -{ - const mbedtls_md_info_t *md_info; - - if( *hash_len != 0 ) - return( 0 ); - - if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) - return( -1 ); - - *hash_len = mbedtls_md_get_size( md_info ); - return( 0 ); -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Helper to set up a restart context if needed - */ -static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx, - const mbedtls_pk_info_t *info ) -{ - /* Don't do anything if already set up or invalid */ - if( ctx == NULL || ctx->pk_info != NULL ) - return( 0 ); - - /* Should never happen when we're called */ - if( info->rs_alloc_func == NULL || info->rs_free_func == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - return( 0 ); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* - * Verify a signature (restartable) - */ -int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - mbedtls_pk_restart_ctx *rs_ctx ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( ctx->pk_info == NULL || - pk_hashlen_helper( md_alg, &hash_len ) != 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if( rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->verify_rs_func != NULL ) - { - int ret; - - if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) - return( ret ); - - ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx, - md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx ); - - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_pk_restart_free( rs_ctx ); - - return( ret ); - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - if( ctx->pk_info->verify_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, - sig, sig_len ) ); -} - -/* - * Verify a signature - */ -int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len, - sig, sig_len, NULL ) ); -} - -/* - * Verify a signature with options - */ -int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, - mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ! mbedtls_pk_can_do( ctx, type ) ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - if( type == MBEDTLS_PK_RSASSA_PSS ) - { -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) - int ret; - const mbedtls_pk_rsassa_pss_options *pss_opts; - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - if( options == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; - - if( sig_len < mbedtls_pk_get_len( ctx ) ) - return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ), - NULL, NULL, MBEDTLS_RSA_PUBLIC, - md_alg, (unsigned int) hash_len, hash, - pss_opts->mgf1_hash_id, - pss_opts->expected_salt_len, - sig ); - if( ret != 0 ) - return( ret ); - - if( sig_len > mbedtls_pk_get_len( ctx ) ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( 0 ); -#else - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ - } - - /* General case: no options */ - if( options != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); -} - -/* - * Make a signature (restartable) - */ -int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_pk_restart_ctx *rs_ctx ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( ctx->pk_info == NULL || - pk_hashlen_helper( md_alg, &hash_len ) != 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if( rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->sign_rs_func != NULL ) - { - int ret; - - if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) - return( ret ); - - ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg, - hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx ); - - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_pk_restart_free( rs_ctx ); - - return( ret ); - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - if( ctx->pk_info->sign_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, - sig, sig_len, f_rng, p_rng ) ); -} - -/* - * Make a signature - */ -int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len, - sig, sig_len, f_rng, p_rng, NULL ) ); -} - -/* - * Decrypt message - */ -int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( input != NULL || ilen == 0 ); - PK_VALIDATE_RET( output != NULL || osize == 0 ); - PK_VALIDATE_RET( olen != NULL ); - - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ctx->pk_info->decrypt_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, - output, olen, osize, f_rng, p_rng ) ); -} - -/* - * Encrypt message - */ -int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( input != NULL || ilen == 0 ); - PK_VALIDATE_RET( output != NULL || osize == 0 ); - PK_VALIDATE_RET( olen != NULL ); - - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ctx->pk_info->encrypt_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, - output, olen, osize, f_rng, p_rng ) ); -} - -/* - * Check public-private key pair - */ -int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ) -{ - PK_VALIDATE_RET( pub != NULL ); - PK_VALIDATE_RET( prv != NULL ); - - if( pub->pk_info == NULL || - prv->pk_info == NULL ) - { - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - } - - if( prv->pk_info->check_pair_func == NULL ) - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT ) - { - if( pub->pk_info->type != MBEDTLS_PK_RSA ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - } - else - { - if( pub->pk_info != prv->pk_info ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - } - - return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) ); -} - -/* - * Get key size in bits - */ -size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) -{ - /* For backward compatibility, accept NULL or a context that - * isn't set up yet, and return a fake value that should be safe. */ - if( ctx == NULL || ctx->pk_info == NULL ) - return( 0 ); - - return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) ); -} - -/* - * Export debug information - */ -int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ) -{ - PK_VALIDATE_RET( ctx != NULL ); - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ctx->pk_info->debug_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - ctx->pk_info->debug_func( ctx->pk_ctx, items ); - return( 0 ); -} - -/* - * Access the PK type name - */ -const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx ) -{ - if( ctx == NULL || ctx->pk_info == NULL ) - return( "invalid PK" ); - - return( ctx->pk_info->name ); -} - -/* - * Access the PK type - */ -mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ) -{ - if( ctx == NULL || ctx->pk_info == NULL ) - return( MBEDTLS_PK_NONE ); - - return( ctx->pk_info->type ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* - * Load the key to a PSA key slot, - * then turn the PK context into a wrapper for that key slot. - * - * Currently only works for EC private keys. - */ -int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk, - psa_key_handle_t *slot, - psa_algorithm_t hash_alg ) -{ -#if !defined(MBEDTLS_ECP_C) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); -#else - psa_key_handle_t key; - const mbedtls_ecp_keypair *ec; - unsigned char d[MBEDTLS_ECP_MAX_BYTES]; - size_t d_len; - psa_ecc_curve_t curve_id; - psa_key_type_t key_type; - psa_key_policy_t policy; - int ret; - - /* export the private key material in the format PSA wants */ - if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - ec = mbedtls_pk_ec( *pk ); - d_len = ( ec->grp.nbits + 7 ) / 8; - if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 ) - return( ret ); - - curve_id = mbedtls_ecp_curve_info_from_grp_id( ec->grp.id )->tls_id; - key_type = PSA_KEY_TYPE_ECC_KEYPAIR( - mbedtls_psa_parse_tls_ecc_group ( curve_id ) ); - - /* allocate a key slot */ - if( PSA_SUCCESS != psa_allocate_key( &key ) ) - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); - - /* set policy */ - policy = psa_key_policy_init(); - psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, - PSA_ALG_ECDSA(hash_alg) ); - if( PSA_SUCCESS != psa_set_key_policy( key, &policy ) ) - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); - - /* import private key in slot */ - if( PSA_SUCCESS != psa_import_key( key, key_type, d, d_len ) ) - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); - - /* remember slot number to be destroyed later by caller */ - *slot = key; - - /* make PK context wrap the key slot */ - mbedtls_pk_free( pk ); - mbedtls_pk_init( pk ); - - return( mbedtls_pk_setup_opaque( pk, key ) ); -#endif /* MBEDTLS_ECP_C */ -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_PK_C */ diff --git a/library/pk_wrap.c b/library/pk_wrap.c deleted file mode 100644 index c7f879ab5a..0000000000 --- a/library/pk_wrap.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * Public Key abstraction layer: wrapper functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk_internal.h" - -/* Even if RSA not activated, for the sake of RSA-alt */ -#include "mbedtls/rsa.h" - -#include - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/asn1write.h" -#endif - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -#include "mbedtls/platform_util.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#include "mbedtls/asn1.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include -#include - -#if defined(MBEDTLS_RSA_C) -static int rsa_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_RSA || - type == MBEDTLS_PK_RSASSA_PSS ); -} - -static size_t rsa_get_bitlen( const void *ctx ) -{ - const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx; - return( 8 * mbedtls_rsa_get_len( rsa ) ); -} - -static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - size_t rsa_len = mbedtls_rsa_get_len( rsa ); - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - if( sig_len < rsa_len ) - return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, - MBEDTLS_RSA_PUBLIC, md_alg, - (unsigned int) hash_len, hash, sig ) ) != 0 ) - return( ret ); - - /* The buffer contains a valid signature followed by extra data. - * We have a special error code for that so that so that callers can - * use mbedtls_pk_verify() to check "Does the buffer start with a - * valid signature?" and not just "Does the buffer contain a valid - * signature?". */ - if( sig_len > rsa_len ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( 0 ); -} - -static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - *sig_len = mbedtls_rsa_get_len( rsa ); - - return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, - md_alg, (unsigned int) hash_len, hash, sig ) ); -} - -static int rsa_decrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - - if( ilen != mbedtls_rsa_get_len( rsa ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, - MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); -} - -static int rsa_encrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - *olen = mbedtls_rsa_get_len( rsa ); - - if( *olen > osize ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); - - return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, - ilen, input, output ) ); -} - -static int rsa_check_pair_wrap( const void *pub, const void *prv ) -{ - return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, - (const mbedtls_rsa_context *) prv ) ); -} - -static void *rsa_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); - - if( ctx != NULL ) - mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); - - return( ctx ); -} - -static void rsa_free_wrap( void *ctx ) -{ - mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); - mbedtls_free( ctx ); -} - -static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) -{ - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.N"; - items->value = &( ((mbedtls_rsa_context *) ctx)->N ); - - items++; - - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.E"; - items->value = &( ((mbedtls_rsa_context *) ctx)->E ); -} - -const mbedtls_pk_info_t mbedtls_rsa_info = { - MBEDTLS_PK_RSA, - "RSA", - rsa_get_bitlen, - rsa_can_do, - rsa_verify_wrap, - rsa_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_decrypt_wrap, - rsa_encrypt_wrap, - rsa_check_pair_wrap, - rsa_alloc_wrap, - rsa_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_debug, -}; -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * Generic EC key - */ -static int eckey_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH || - type == MBEDTLS_PK_ECDSA ); -} - -static size_t eckey_get_bitlen( const void *ctx ) -{ - return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); -} - -#if defined(MBEDTLS_ECDSA_C) -/* Forward declarations */ -static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ); - -static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - mbedtls_ecdsa_context ecdsa; - - mbedtls_ecdsa_init( &ecdsa ); - - if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) - ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); - - mbedtls_ecdsa_free( &ecdsa ); - - return( ret ); -} - -static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_ecdsa_context ecdsa; - - mbedtls_ecdsa_init( &ecdsa ); - - if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) - ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, - f_rng, p_rng ); - - mbedtls_ecdsa_free( &ecdsa ); - - return( ret ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* Forward declarations */ -static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ); - -static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ); - -/* - * Restart context for ECDSA operations with ECKEY context - * - * We need to store an actual ECDSA context, as we need to pass the same to - * the underlying ecdsa function, so we can't create it on the fly every time. - */ -typedef struct -{ - mbedtls_ecdsa_restart_ctx ecdsa_rs; - mbedtls_ecdsa_context ecdsa_ctx; -} eckey_restart_ctx; - -static void *eckey_rs_alloc( void ) -{ - eckey_restart_ctx *rs_ctx; - - void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) ); - - if( ctx != NULL ) - { - rs_ctx = ctx; - mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs ); - mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx ); - } - - return( ctx ); -} - -static void eckey_rs_free( void *ctx ) -{ - eckey_restart_ctx *rs_ctx; - - if( ctx == NULL) - return; - - rs_ctx = ctx; - mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); - mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); - - mbedtls_free( ctx ); -} - -static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ) -{ - int ret; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if( rs == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* set up our own sub-context if needed (that is, on first run) */ - if( rs->ecdsa_ctx.grp.pbits == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); - - MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, - md_alg, hash, hash_len, - sig, sig_len, &rs->ecdsa_rs ) ); - -cleanup: - return( ret ); -} - -static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ) -{ - int ret; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if( rs == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* set up our own sub-context if needed (that is, on first run) */ - if( rs->ecdsa_ctx.grp.pbits == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); - - MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg, - hash, hash_len, sig, sig_len, - f_rng, p_rng, &rs->ecdsa_rs ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_ECDSA_C */ - -static int eckey_check_pair( const void *pub, const void *prv ) -{ - return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, - (const mbedtls_ecp_keypair *) prv ) ); -} - -static void *eckey_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); - - if( ctx != NULL ) - mbedtls_ecp_keypair_init( ctx ); - - return( ctx ); -} - -static void eckey_free_wrap( void *ctx ) -{ - mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); - mbedtls_free( ctx ); -} - -static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) -{ - items->type = MBEDTLS_PK_DEBUG_ECP; - items->name = "eckey.Q"; - items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); -} - -const mbedtls_pk_info_t mbedtls_eckey_info = { - MBEDTLS_PK_ECKEY, - "EC", - eckey_get_bitlen, - eckey_can_do, -#if defined(MBEDTLS_ECDSA_C) - eckey_verify_wrap, - eckey_sign_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - eckey_verify_rs_wrap, - eckey_sign_rs_wrap, -#endif -#else /* MBEDTLS_ECDSA_C */ - NULL, - NULL, -#endif /* MBEDTLS_ECDSA_C */ - NULL, - NULL, - eckey_check_pair, - eckey_alloc_wrap, - eckey_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - eckey_rs_alloc, - eckey_rs_free, -#endif - eckey_debug, -}; - -/* - * EC key restricted to ECDH - */ -static int eckeydh_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH ); -} - -const mbedtls_pk_info_t mbedtls_eckeydh_info = { - MBEDTLS_PK_ECKEY_DH, - "EC_DH", - eckey_get_bitlen, /* Same underlying key structure */ - eckeydh_can_do, - NULL, - NULL, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - NULL, - NULL, - eckey_check_pair, - eckey_alloc_wrap, /* Same underlying key structure */ - eckey_free_wrap, /* Same underlying key structure */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - eckey_debug, /* Same underlying key structure */ -}; -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_ECDSA_C) -static int ecdsa_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECDSA ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* - * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of - * those integers and convert it to the fixed-length encoding expected by PSA. - */ -static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end, - unsigned char *to, size_t to_len ) -{ - int ret; - size_t unpadded_len, padding_len; - - if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len, - MBEDTLS_ASN1_INTEGER ) ) != 0 ) - { - return( ret ); - } - - while( unpadded_len > 0 && **from == 0x00 ) - { - ( *from )++; - unpadded_len--; - } - - if( unpadded_len > to_len || unpadded_len == 0 ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - padding_len = to_len - unpadded_len; - memset( to, 0x00, padding_len ); - memcpy( to + padding_len, *from, unpadded_len ); - ( *from ) += unpadded_len; - - return( 0 ); -} - -/* - * Convert a signature from an ASN.1 sequence of two integers - * to a raw {r,s} buffer. Note: the provided sig buffer must be at least - * twice as big as int_size. - */ -static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end, - unsigned char *sig, size_t int_size ) -{ - int ret; - size_t tmp_size; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - /* Extract r */ - if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 ) - return( ret ); - /* Extract s */ - if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - psa_key_handle_t key_slot; - psa_key_policy_t policy; - psa_key_type_t psa_type; - mbedtls_pk_context key; - int key_len; - /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */ - unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES]; - unsigned char *p; - mbedtls_pk_info_t pk_info = mbedtls_eckey_info; - psa_algorithm_t psa_sig_md, psa_md; - psa_ecc_curve_t curve = mbedtls_psa_translate_ecc_group( - ( (mbedtls_ecdsa_context *) ctx )->grp.id ); - const size_t signature_part_size = ( ( (mbedtls_ecdsa_context *) ctx )->grp.nbits + 7 ) / 8; - - if( curve == 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* mbedtls_pk_write_pubkey() expects a full PK context; - * re-construct one to make it happy */ - key.pk_info = &pk_info; - key.pk_ctx = ctx; - p = buf + sizeof( buf ); - key_len = mbedtls_pk_write_pubkey( &p, buf, &key ); - if( key_len <= 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - psa_md = mbedtls_psa_translate_md( md_alg ); - if( psa_md == 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - psa_sig_md = PSA_ALG_ECDSA( psa_md ); - psa_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ); - - if( ( ret = psa_allocate_key( &key_slot ) ) != PSA_SUCCESS ) - return( mbedtls_psa_err_translate_pk( ret ) ); - - policy = psa_key_policy_init(); - psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, psa_sig_md ); - if( ( ret = psa_set_key_policy( key_slot, &policy ) ) != PSA_SUCCESS ) - { - ret = mbedtls_psa_err_translate_pk( ret ); - goto cleanup; - } - - if( psa_import_key( key_slot, psa_type, buf + sizeof( buf ) - key_len, key_len ) - != PSA_SUCCESS ) - { - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - goto cleanup; - } - - /* We don't need the exported key anymore and can - * reuse its buffer for signature extraction. */ - if( 2 * signature_part_size > sizeof( buf ) ) - { - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - goto cleanup; - } - - p = (unsigned char*) sig; - if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf, - signature_part_size ) ) != 0 ) - { - goto cleanup; - } - - if( psa_asymmetric_verify( key_slot, psa_sig_md, - hash, hash_len, - buf, 2 * signature_part_size ) - != PSA_SUCCESS ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - - if( p != sig + sig_len ) - { - ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; - goto cleanup; - } - ret = 0; - -cleanup: - psa_destroy_key( key_slot ); - return( ret ); -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, - hash, hash_len, sig, sig_len ); - - if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( ret ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, - md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ) -{ - int ret; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature_restartable( - (mbedtls_ecdsa_context *) ctx, - hash, hash_len, sig, sig_len, - (mbedtls_ecdsa_restart_ctx *) rs_ctx ); - - if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( ret ); -} - -static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ) -{ - return( mbedtls_ecdsa_write_signature_restartable( - (mbedtls_ecdsa_context *) ctx, - md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng, - (mbedtls_ecdsa_restart_ctx *) rs_ctx ) ); - -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -static void *ecdsa_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); - - if( ctx != NULL ) - mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); - - return( ctx ); -} - -static void ecdsa_free_wrap( void *ctx ) -{ - mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); - mbedtls_free( ctx ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -static void *ecdsa_rs_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) ); - - if( ctx != NULL ) - mbedtls_ecdsa_restart_init( ctx ); - - return( ctx ); -} - -static void ecdsa_rs_free( void *ctx ) -{ - mbedtls_ecdsa_restart_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -const mbedtls_pk_info_t mbedtls_ecdsa_info = { - MBEDTLS_PK_ECDSA, - "ECDSA", - eckey_get_bitlen, /* Compatible key structures */ - ecdsa_can_do, - ecdsa_verify_wrap, - ecdsa_sign_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - ecdsa_verify_rs_wrap, - ecdsa_sign_rs_wrap, -#endif - NULL, - NULL, - eckey_check_pair, /* Compatible key structures */ - ecdsa_alloc_wrap, - ecdsa_free_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - ecdsa_rs_alloc, - ecdsa_rs_free, -#endif - eckey_debug, /* Compatible key structures */ -}; -#endif /* MBEDTLS_ECDSA_C */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* - * Support for alternative RSA-private implementations - */ - -static int rsa_alt_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_RSA ); -} - -static size_t rsa_alt_get_bitlen( const void *ctx ) -{ - const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; - - return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); -} - -static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; - -#if SIZE_MAX > UINT_MAX - if( UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - *sig_len = rsa_alt->key_len_func( rsa_alt->key ); - - return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, - md_alg, (unsigned int) hash_len, hash, sig ) ); -} - -static int rsa_alt_decrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; - - ((void) f_rng); - ((void) p_rng); - - if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - return( rsa_alt->decrypt_func( rsa_alt->key, - MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); -} - -#if defined(MBEDTLS_RSA_C) -static int rsa_alt_check_pair( const void *pub, const void *prv ) -{ - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; - unsigned char hash[32]; - size_t sig_len = 0; - int ret; - - if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - - memset( hash, 0x2a, sizeof( hash ) ); - - if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, - hash, sizeof( hash ), - sig, &sig_len, NULL, NULL ) ) != 0 ) - { - return( ret ); - } - - if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, - hash, sizeof( hash ), sig, sig_len ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - return( 0 ); -} -#endif /* MBEDTLS_RSA_C */ - -static void *rsa_alt_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); - - if( ctx != NULL ) - memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); - - return( ctx ); -} - -static void rsa_alt_free_wrap( void *ctx ) -{ - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); - mbedtls_free( ctx ); -} - -const mbedtls_pk_info_t mbedtls_rsa_alt_info = { - MBEDTLS_PK_RSA_ALT, - "RSA-alt", - rsa_alt_get_bitlen, - rsa_alt_can_do, - NULL, - rsa_alt_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_alt_decrypt_wrap, - NULL, -#if defined(MBEDTLS_RSA_C) - rsa_alt_check_pair, -#else - NULL, -#endif - rsa_alt_alloc_wrap, - rsa_alt_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - NULL, -}; - -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - -static void *pk_opaque_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( psa_key_handle_t ) ); - - /* no _init() function to call, an calloc() already zeroized */ - - return( ctx ); -} - -static void pk_opaque_free_wrap( void *ctx ) -{ - mbedtls_platform_zeroize( ctx, sizeof( psa_key_handle_t ) ); - mbedtls_free( ctx ); -} - -static size_t pk_opaque_get_bitlen( const void *ctx ) -{ - const psa_key_handle_t *key = (const psa_key_handle_t *) ctx; - size_t bits; - - if( PSA_SUCCESS != psa_get_key_information( *key, NULL, &bits ) ) - return( 0 ); - - return( bits ); -} - -static int pk_opaque_can_do( mbedtls_pk_type_t type ) -{ - /* For now opaque PSA keys can only wrap ECC keypairs, - * as checked by setup_psa(). - * Also, ECKEY_DH does not really make sense with the current API. */ - return( type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECDSA ); -} - -/* - * Simultaneously convert and move raw MPI from the beginning of a buffer - * to an ASN.1 MPI at the end of the buffer. - * See also mbedtls_asn1_write_mpi(). - * - * p: pointer to the end of the output buffer - * start: start of the output buffer, and also of the mpi to write at the end - * n_len: length of the mpi to read from start - */ -static int asn1_write_mpibuf( unsigned char **p, unsigned char *start, - size_t n_len ) -{ - int ret; - size_t len = 0; - - if( (size_t)( *p - start ) < n_len ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len = n_len; - *p -= len; - memmove( *p, start, len ); - - /* ASN.1 DER encoding requires minimal length, so skip leading 0s. - * Neither r nor s should be 0, but as a failsafe measure, still detect - * that rather than overflowing the buffer in case of a PSA error. */ - while( len > 0 && **p == 0x00 ) - { - ++(*p); - --len; - } - - /* this is only reached if the signature was invalid */ - if( len == 0 ) - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); - - /* if the msb is 1, ASN.1 requires that we prepend a 0. - * Neither r nor s can be 0, so we can assume len > 0 at all times. */ - if( **p & 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = 0x00; - len += 1; - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, - MBEDTLS_ASN1_INTEGER ) ); - - return( (int) len ); -} - -/* Transcode signature from PSA format to ASN.1 sequence. - * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of - * MPIs, and in-place. - * - * [in/out] sig: the signature pre- and post-transcoding - * [in/out] sig_len: signature length pre- and post-transcoding - * [int] buf_len: the available size the in/out buffer - */ -static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len, - size_t buf_len ) -{ - int ret; - size_t len = 0; - const size_t rs_len = *sig_len / 2; - unsigned char *p = sig + buf_len; - - MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - memmove( sig, p, len ); - *sig_len = len; - - return( 0 ); -} - -static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - const psa_key_handle_t *key = (const psa_key_handle_t *) ctx; - psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) ); - size_t bits, buf_len; - psa_status_t status; - - /* PSA has its own RNG */ - (void) f_rng; - (void) p_rng; - - /* PSA needs an output buffer of known size, but our API doesn't provide - * that information. Assume that the buffer is large enough for a - * maximal-length signature with that key (otherwise the application is - * buggy anyway). */ - status = psa_get_key_information( *key, NULL, &bits ); - if( status != PSA_SUCCESS ) - return( mbedtls_psa_err_translate_pk( status ) ); - - buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( bits ); - - /* make the signature */ - status = psa_asymmetric_sign( *key, alg, hash, hash_len, - sig, buf_len, sig_len ); - if( status != PSA_SUCCESS ) - return( mbedtls_psa_err_translate_pk( status ) ); - - /* transcode it to ASN.1 sequence */ - return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) ); -} - -const mbedtls_pk_info_t mbedtls_pk_opaque_info = { - MBEDTLS_PK_OPAQUE, - "Opaque", - pk_opaque_get_bitlen, - pk_opaque_can_do, - NULL, /* verify - will be done later */ - pk_opaque_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, /* restartable verify - not relevant */ - NULL, /* restartable sign - not relevant */ -#endif - NULL, /* decrypt - will be done later */ - NULL, /* encrypt - will be done later */ - NULL, /* check_pair - could be done later or left NULL */ - pk_opaque_alloc_wrap, - pk_opaque_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, /* restart alloc - not relevant */ - NULL, /* restart free - not relevant */ -#endif - NULL, /* debug - could be done later, or even left NULL */ -}; - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#endif /* MBEDTLS_PK_C */ diff --git a/library/pkcs12.c b/library/pkcs12.c deleted file mode 100644 index 7edf064c13..0000000000 --- a/library/pkcs12.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * PKCS#12 Personal Information Exchange Syntax - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 - * - * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PKCS12_C) - -#include "mbedtls/pkcs12.h" -#include "mbedtls/asn1.h" -#include "mbedtls/cipher.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) - -static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, - mbedtls_asn1_buf *salt, int *iterations ) -{ - int ret; - unsigned char **p = ¶ms->p; - const unsigned char *end = params->p + params->len; - - /* - * pkcs-12PbeParams ::= SEQUENCE { - * salt OCTET STRING, - * iterations INTEGER - * } - * - */ - if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); - - salt->p = *p; - *p += salt->len; - - if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); - - if( *p != end ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -#define PKCS12_MAX_PWDLEN 128 - -static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - unsigned char *key, size_t keylen, - unsigned char *iv, size_t ivlen ) -{ - int ret, iterations = 0; - mbedtls_asn1_buf salt; - size_t i; - unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; - - if( pwdlen > PKCS12_MAX_PWDLEN ) - return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); - - memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); - memset( &unipwd, 0, sizeof(unipwd) ); - - if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, - &iterations ) ) != 0 ) - return( ret ); - - for( i = 0; i < pwdlen; i++ ) - unipwd[i * 2 + 1] = pwd[i]; - - if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, - salt.p, salt.len, md_type, - MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 ) - { - return( ret ); - } - - if( iv == NULL || ivlen == 0 ) - return( 0 ); - - if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, - salt.p, salt.len, md_type, - MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 ) - { - return( ret ); - } - return( 0 ); -} - -#undef PKCS12_MAX_PWDLEN - -int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output ) -{ -#if !defined(MBEDTLS_ARC4_C) - ((void) pbe_params); - ((void) mode); - ((void) pwd); - ((void) pwdlen); - ((void) data); - ((void) len); - ((void) output); - return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); -#else - int ret; - unsigned char key[16]; - mbedtls_arc4_context ctx; - ((void) mode); - - mbedtls_arc4_init( &ctx ); - - if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1, - pwd, pwdlen, - key, 16, NULL, 0 ) ) != 0 ) - { - return( ret ); - } - - mbedtls_arc4_setup( &ctx, key, 16 ); - if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_arc4_free( &ctx ); - - return( ret ); -#endif /* MBEDTLS_ARC4_C */ -} - -int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output ) -{ - int ret, keylen = 0; - unsigned char key[32]; - unsigned char iv[16]; - const mbedtls_cipher_info_t *cipher_info; - mbedtls_cipher_context_t cipher_ctx; - size_t olen = 0; - - cipher_info = mbedtls_cipher_info_from_type( cipher_type ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); - - keylen = cipher_info->key_bitlen / 8; - - if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, - key, keylen, - iv, cipher_info->iv_size ) ) != 0 ) - { - return( ret ); - } - - mbedtls_cipher_init( &cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, - output, &olen ) ) != 0 ) - { - goto exit; - } - - if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) - ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; - -exit: - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_platform_zeroize( iv, sizeof( iv ) ); - mbedtls_cipher_free( &cipher_ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_ASN1_PARSE_C */ - -static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, - const unsigned char *filler, size_t fill_len ) -{ - unsigned char *p = data; - size_t use_len; - - while( data_len > 0 ) - { - use_len = ( data_len > fill_len ) ? fill_len : data_len; - memcpy( p, filler, use_len ); - p += use_len; - data_len -= use_len; - } -} - -int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *salt, size_t saltlen, - mbedtls_md_type_t md_type, int id, int iterations ) -{ - int ret; - unsigned int j; - - unsigned char diversifier[128]; - unsigned char salt_block[128], pwd_block[128], hash_block[128]; - unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; - unsigned char *p; - unsigned char c; - - size_t hlen, use_len, v, i; - - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - // This version only allows max of 64 bytes of password or salt - if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) - return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); - - md_info = mbedtls_md_info_from_type( md_type ); - if( md_info == NULL ) - return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); - - mbedtls_md_init( &md_ctx ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - return( ret ); - hlen = mbedtls_md_get_size( md_info ); - - if( hlen <= 32 ) - v = 64; - else - v = 128; - - memset( diversifier, (unsigned char) id, v ); - - pkcs12_fill_buffer( salt_block, v, salt, saltlen ); - pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); - - p = data; - while( datalen > 0 ) - { - // Calculate hash( diversifier || salt_block || pwd_block ) - if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) - goto exit; - - // Perform remaining ( iterations - 1 ) recursive hash calculations - for( i = 1; i < (size_t) iterations; i++ ) - { - if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) - goto exit; - } - - use_len = ( datalen > hlen ) ? hlen : datalen; - memcpy( p, hash_output, use_len ); - datalen -= use_len; - p += use_len; - - if( datalen == 0 ) - break; - - // Concatenating copies of hash_output into hash_block (B) - pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); - - // B += 1 - for( i = v; i > 0; i-- ) - if( ++hash_block[i - 1] != 0 ) - break; - - // salt_block += B - c = 0; - for( i = v; i > 0; i-- ) - { - j = salt_block[i - 1] + hash_block[i - 1] + c; - c = (unsigned char) (j >> 8); - salt_block[i - 1] = j & 0xFF; - } - - // pwd_block += B - c = 0; - for( i = v; i > 0; i-- ) - { - j = pwd_block[i - 1] + hash_block[i - 1] + c; - c = (unsigned char) (j >> 8); - pwd_block[i - 1] = j & 0xFF; - } - } - - ret = 0; - -exit: - mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); - mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); - mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); - mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); - - mbedtls_md_free( &md_ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_PKCS12_C */ diff --git a/library/pkcs5.c b/library/pkcs5.c deleted file mode 100644 index e7d805c2c6..0000000000 --- a/library/pkcs5.c +++ /dev/null @@ -1,417 +0,0 @@ -/** - * \file pkcs5.c - * - * \brief PKCS#5 functions - * - * \author Mathias Olsson - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * PKCS#5 includes PBKDF2 and more - * - * http://tools.ietf.org/html/rfc2898 (Specification) - * http://tools.ietf.org/html/rfc6070 (Test vectors) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PKCS5_C) - -#include "mbedtls/pkcs5.h" - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#include "mbedtls/cipher.h" -#include "mbedtls/oid.h" -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) -static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, - mbedtls_asn1_buf *salt, int *iterations, - int *keylen, mbedtls_md_type_t *md_type ) -{ - int ret; - mbedtls_asn1_buf prf_alg_oid; - unsigned char *p = params->p; - const unsigned char *end = params->p + params->len; - - if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - /* - * PBKDF2-params ::= SEQUENCE { - * salt OCTET STRING, - * iterationCount INTEGER, - * keyLength INTEGER OPTIONAL - * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1 - * } - * - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, - MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - salt->p = p; - p += salt->len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - if( p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 ) - { - if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - } - - if( p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - if( p != end ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output ) -{ - int ret, iterations = 0, keylen = 0; - unsigned char *p, *end; - mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params; - mbedtls_asn1_buf salt; - mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; - unsigned char key[32], iv[32]; - size_t olen = 0; - const mbedtls_md_info_t *md_info; - const mbedtls_cipher_info_t *cipher_info; - mbedtls_md_context_t md_ctx; - mbedtls_cipher_type_t cipher_alg; - mbedtls_cipher_context_t cipher_ctx; - - p = pbe_params->p; - end = p + pbe_params->len; - - /* - * PBES2-params ::= SEQUENCE { - * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, - * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} - * } - */ - if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, - &kdf_alg_params ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - // Only PBKDF2 supported at the moment - // - if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params, - &salt, &iterations, &keylen, - &md_type ) ) != 0 ) - { - return( ret ); - } - - md_info = mbedtls_md_info_from_type( md_type ); - if( md_info == NULL ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid, - &enc_scheme_params ) ) != 0 ) - { - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - } - - if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - cipher_info = mbedtls_cipher_info_from_type( cipher_alg ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - /* - * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored - * since it is optional and we don't know if it was set or not - */ - keylen = cipher_info->key_bitlen / 8; - - if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING || - enc_scheme_params.len != cipher_info->iv_size ) - { - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT ); - } - - mbedtls_md_init( &md_ctx ); - mbedtls_cipher_init( &cipher_ctx ); - - memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, - iterations, keylen, key ) ) != 0 ) - { - goto exit; - } - - if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, - (mbedtls_operation_t) mode ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len, - data, datalen, output, &olen ) ) != 0 ) - ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH; - -exit: - mbedtls_md_free( &md_ctx ); - mbedtls_cipher_free( &cipher_ctx ); - - return( ret ); -} -#endif /* MBEDTLS_ASN1_PARSE_C */ - -int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, - const unsigned char *password, - size_t plen, const unsigned char *salt, size_t slen, - unsigned int iteration_count, - uint32_t key_length, unsigned char *output ) -{ - int ret, j; - unsigned int i; - unsigned char md1[MBEDTLS_MD_MAX_SIZE]; - unsigned char work[MBEDTLS_MD_MAX_SIZE]; - unsigned char md_size = mbedtls_md_get_size( ctx->md_info ); - size_t use_len; - unsigned char *out_p = output; - unsigned char counter[4]; - - memset( counter, 0, 4 ); - counter[3] = 1; - -#if UINT_MAX > 0xFFFFFFFF - if( iteration_count > 0xFFFFFFFF ) - return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA ); -#endif - - while( key_length ) - { - // U1 ends up in work - // - if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 ) - return( ret ); - - memcpy( md1, work, md_size ); - - for( i = 1; i < iteration_count; i++ ) - { - // U2 ends up in md1 - // - if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 ) - return( ret ); - - // U1 xor U2 - // - for( j = 0; j < md_size; j++ ) - work[j] ^= md1[j]; - } - - use_len = ( key_length < md_size ) ? key_length : md_size; - memcpy( out_p, work, use_len ); - - key_length -= (uint32_t) use_len; - out_p += use_len; - - for( i = 4; i > 0; i-- ) - if( ++counter[i - 1] != 0 ) - break; - } - - return( 0 ); -} - -#if defined(MBEDTLS_SELF_TEST) - -#if !defined(MBEDTLS_SHA1_C) -int mbedtls_pkcs5_self_test( int verbose ) -{ - if( verbose != 0 ) - mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" ); - - return( 0 ); -} -#else - -#define MAX_TESTS 6 - -static const size_t plen_test_data[MAX_TESTS] = - { 8, 8, 8, 24, 9 }; - -static const unsigned char password_test_data[MAX_TESTS][32] = -{ - "password", - "password", - "password", - "passwordPASSWORDpassword", - "pass\0word", -}; - -static const size_t slen_test_data[MAX_TESTS] = - { 4, 4, 4, 36, 5 }; - -static const unsigned char salt_test_data[MAX_TESTS][40] = -{ - "salt", - "salt", - "salt", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - "sa\0lt", -}; - -static const uint32_t it_cnt_test_data[MAX_TESTS] = - { 1, 2, 4096, 4096, 4096 }; - -static const uint32_t key_len_test_data[MAX_TESTS] = - { 20, 20, 20, 25, 16 }; - -static const unsigned char result_key_test_data[MAX_TESTS][32] = -{ - { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, - 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, - 0x2f, 0xe0, 0x37, 0xa6 }, - { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, - 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, - 0xd8, 0xde, 0x89, 0x57 }, - { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, - 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, - 0x65, 0xa4, 0x29, 0xc1 }, - { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, - 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, - 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, - 0x38 }, - { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, - 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 }, -}; - -int mbedtls_pkcs5_self_test( int verbose ) -{ - mbedtls_md_context_t sha1_ctx; - const mbedtls_md_info_t *info_sha1; - int ret, i; - unsigned char key[64]; - - mbedtls_md_init( &sha1_ctx ); - - info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); - if( info_sha1 == NULL ) - { - ret = 1; - goto exit; - } - - if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 ) - { - ret = 1; - goto exit; - } - - for( i = 0; i < MAX_TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i ); - - ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password_test_data[i], - plen_test_data[i], salt_test_data[i], - slen_test_data[i], it_cnt_test_data[i], - key_len_test_data[i], key ); - if( ret != 0 || - memcmp( result_key_test_data[i], key, key_len_test_data[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_md_free( &sha1_ctx ); - - return( ret ); -} -#endif /* MBEDTLS_SHA1_C */ - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_PKCS5_C */ diff --git a/library/pkparse.c b/library/pkparse.c deleted file mode 100644 index ae210bca6a..0000000000 --- a/library/pkparse.c +++ /dev/null @@ -1,1482 +0,0 @@ -/* - * Public Key layer for parsing key files and structures - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_PARSE_C) - -#include "mbedtls/pk.h" -#include "mbedtls/asn1.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif -#if defined(MBEDTLS_PKCS5_C) -#include "mbedtls/pkcs5.h" -#endif -#if defined(MBEDTLS_PKCS12_C) -#include "mbedtls/pkcs12.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_FS_IO) -/* - * Load all data from a file into a given buffer. - * - * The file is expected to contain either PEM or DER encoded data. - * A terminating null byte is always appended. It is included in the announced - * length only if the data looks like it is PEM encoded. - */ -int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) -{ - FILE *f; - long size; - - PK_VALIDATE_RET( path != NULL ); - PK_VALIDATE_RET( buf != NULL ); - PK_VALIDATE_RET( n != NULL ); - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); - - fseek( f, 0, SEEK_END ); - if( ( size = ftell( f ) ) == -1 ) - { - fclose( f ); - return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); - } - fseek( f, 0, SEEK_SET ); - - *n = (size_t) size; - - if( *n + 1 == 0 || - ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) - { - fclose( f ); - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - } - - if( fread( *buf, 1, *n, f ) != *n ) - { - fclose( f ); - - mbedtls_platform_zeroize( *buf, *n ); - mbedtls_free( *buf ); - - return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); - } - - fclose( f ); - - (*buf)[*n] = '\0'; - - if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) - ++*n; - - return( 0 ); -} - -/* - * Load and parse a private key - */ -int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, - const char *path, const char *pwd ) -{ - int ret; - size_t n; - unsigned char *buf; - - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( path != NULL ); - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - if( pwd == NULL ) - ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 ); - else - ret = mbedtls_pk_parse_key( ctx, buf, n, - (const unsigned char *) pwd, strlen( pwd ) ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} - -/* - * Load and parse a public key - */ -int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( path != NULL ); - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_pk_parse_public_key( ctx, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_ECP_C) -/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } - * -- implicitCurve NULL - * } - */ -static int pk_get_ecparams( unsigned char **p, const unsigned char *end, - mbedtls_asn1_buf *params ) -{ - int ret; - - if ( end - *p < 1 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - /* Tag may be either OID or SEQUENCE */ - params->tag = **p; - if( params->tag != MBEDTLS_ASN1_OID -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) - && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) -#endif - ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } - - if( ( ret = mbedtls_asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - params->p = *p; - *p += params->len; - - if( *p != end ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) -/* - * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. - * WARNING: the resulting group should only be used with - * pk_group_id_from_specified(), since its base point may not be set correctly - * if it was encoded compressed. - * - * SpecifiedECDomain ::= SEQUENCE { - * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), - * fieldID FieldID {{FieldTypes}}, - * curve Curve, - * base ECPoint, - * order INTEGER, - * cofactor INTEGER OPTIONAL, - * hash HashAlgorithm OPTIONAL, - * ... - * } - * - * We only support prime-field as field type, and ignore hash and cofactor. - */ -static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) -{ - int ret; - unsigned char *p = params->p; - const unsigned char * const end = params->p + params->len; - const unsigned char *end_field, *end_curve; - size_t len; - int ver; - - /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ - if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ver < 1 || ver > 3 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - - /* - * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field - * fieldType FIELD-ID.&id({IOSet}), - * parameters FIELD-ID.&Type({IOSet}{@fieldType}) - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - end_field = p + len; - - /* - * FIELD-ID ::= TYPE-IDENTIFIER - * FieldTypes FIELD-ID ::= { - * { Prime-p IDENTIFIED BY prime-field } | - * { Characteristic-two IDENTIFIED BY characteristic-two-field } - * } - * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( ret ); - - if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) || - memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) - { - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - } - - p += len; - - /* Prime-p ::= INTEGER -- Field of size p. */ - if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - - if( p != end_field ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* - * Curve ::= SEQUENCE { - * a FieldElement, - * b FieldElement, - * seed BIT STRING OPTIONAL - * -- Shall be present if used in SpecifiedECDomain - * -- with version equal to ecdpVer2 or ecdpVer3 - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - end_curve = p + len; - - /* - * FieldElement ::= OCTET STRING - * containing an integer in the case of a prime field - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || - ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - p += len; - - if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || - ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - p += len; - - /* Ignore seed BIT STRING OPTIONAL */ - if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 ) - p += len; - - if( p != end_curve ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* - * ECPoint ::= OCTET STRING - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G, - ( const unsigned char *) p, len ) ) != 0 ) - { - /* - * If we can't read the point because it's compressed, cheat by - * reading only the X coordinate and the parity bit of Y. - */ - if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || - ( p[0] != 0x02 && p[0] != 0x03 ) || - len != mbedtls_mpi_size( &grp->P ) + 1 || - mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 || - mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 || - mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - } - } - - p += len; - - /* - * order INTEGER - */ - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - grp->nbits = mbedtls_mpi_bitlen( &grp->N ); - - /* - * Allow optional elements by purposefully not enforcing p == end here. - */ - - return( 0 ); -} - -/* - * Find the group id associated with an (almost filled) group as generated by - * pk_group_from_specified(), or return an error if unknown. - */ -static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id ) -{ - int ret = 0; - mbedtls_ecp_group ref; - const mbedtls_ecp_group_id *id; - - mbedtls_ecp_group_init( &ref ); - - for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ ) - { - /* Load the group associated to that id */ - mbedtls_ecp_group_free( &ref ); - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) ); - - /* Compare to the group we were given, starting with easy tests */ - if( grp->pbits == ref.pbits && grp->nbits == ref.nbits && - mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 && - /* For Y we may only know the parity bit, so compare only that */ - mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) ) - { - break; - } - - } - -cleanup: - mbedtls_ecp_group_free( &ref ); - - *grp_id = *id; - - if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE ) - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - - return( ret ); -} - -/* - * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID - */ -static int pk_group_id_from_specified( const mbedtls_asn1_buf *params, - mbedtls_ecp_group_id *grp_id ) -{ - int ret; - mbedtls_ecp_group grp; - - mbedtls_ecp_group_init( &grp ); - - if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 ) - goto cleanup; - - ret = pk_group_id_from_group( &grp, grp_id ); - -cleanup: - mbedtls_ecp_group_free( &grp ); - - return( ret ); -} -#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ - -/* - * Use EC parameters to initialise an EC group - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } - * -- implicitCurve NULL - */ -static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) -{ - int ret; - mbedtls_ecp_group_id grp_id; - - if( params->tag == MBEDTLS_ASN1_OID ) - { - if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 ) - return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); - } - else - { -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) - if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 ) - return( ret ); -#else - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); -#endif - } - - /* - * grp may already be initilialized; if so, make sure IDs match - */ - if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - - if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * EC public key is an EC point - * - * The caller is responsible for clearing the structure upon failure if - * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE - * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state. - */ -static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, - mbedtls_ecp_keypair *key ) -{ - int ret; - - if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q, - (const unsigned char *) *p, end - *p ) ) == 0 ) - { - ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q ); - } - - /* - * We know mbedtls_ecp_point_read_binary consumed all bytes or failed - */ - *p = (unsigned char *) end; - - return( ret ); -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_RSA_C) -/* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ -static int pk_get_rsapubkey( unsigned char **p, - const unsigned char *end, - mbedtls_rsa_context *rsa ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* Import N */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0, - NULL, 0, NULL, 0 ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - - *p += len; - - /* Import E */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, *p, len ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - - *p += len; - - if( mbedtls_rsa_complete( rsa ) != 0 || - mbedtls_rsa_check_pubkey( rsa ) != 0 ) - { - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - } - - if( *p != end ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} -#endif /* MBEDTLS_RSA_C */ - -/* Get a PK algorithm identifier - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ -static int pk_get_pk_alg( unsigned char **p, - const unsigned char *end, - mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params ) -{ - int ret; - mbedtls_asn1_buf alg_oid; - - memset( params, 0, sizeof(mbedtls_asn1_buf) ); - - if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_ALG + ret ); - - if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - /* - * No parameters with RSA (only for EC) - */ - if( *pk_alg == MBEDTLS_PK_RSA && - ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) || - params->len != 0 ) ) - { - return( MBEDTLS_ERR_PK_INVALID_ALG ); - } - - return( 0 ); -} - -/* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ -int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, - mbedtls_pk_context *pk ) -{ - int ret; - size_t len; - mbedtls_asn1_buf alg_params; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - const mbedtls_pk_info_t *pk_info; - - PK_VALIDATE_RET( p != NULL ); - PK_VALIDATE_RET( *p != NULL ); - PK_VALIDATE_RET( end != NULL ); - PK_VALIDATE_RET( pk != NULL ); - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = *p + len; - - if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_RSA_C) - if( pk_alg == MBEDTLS_PK_RSA ) - { - ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) ); - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) - if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY ) - { - ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp ); - if( ret == 0 ) - ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) ); - } else -#endif /* MBEDTLS_ECP_C */ - ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - - if( ret == 0 && *p != end ) - ret = MBEDTLS_ERR_PK_INVALID_PUBKEY - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - - if( ret != 0 ) - mbedtls_pk_free( pk ); - - return( ret ); -} - -#if defined(MBEDTLS_RSA_C) -/* - * Parse a PKCS#1 encoded private RSA key - */ -static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, - const unsigned char *key, - size_t keylen ) -{ - int ret, version; - size_t len; - unsigned char *p, *end; - - mbedtls_mpi T; - mbedtls_mpi_init( &T ); - - p = (unsigned char *) key; - end = p + keylen; - - /* - * This function parses the RSAPrivateKey (PKCS#1) - * - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - if( version != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); - } - - /* Import N */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0, - NULL, 0, NULL, 0 ) ) != 0 ) - goto cleanup; - p += len; - - /* Import E */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, p, len ) ) != 0 ) - goto cleanup; - p += len; - - /* Import D */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, - p, len, NULL, 0 ) ) != 0 ) - goto cleanup; - p += len; - - /* Import P */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0, - NULL, 0, NULL, 0 ) ) != 0 ) - goto cleanup; - p += len; - - /* Import Q */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_INTEGER ) ) != 0 || - ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len, - NULL, 0, NULL, 0 ) ) != 0 ) - goto cleanup; - p += len; - - /* Complete the RSA private key */ - if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 ) - goto cleanup; - - /* Check optional parameters */ - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ) - goto cleanup; - - if( p != end ) - { - ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ; - } - -cleanup: - - mbedtls_mpi_free( &T ); - - if( ret != 0 ) - { - /* Wrap error code if it's coming from a lower level */ - if( ( ret & 0xff80 ) == 0 ) - ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret; - else - ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - - mbedtls_rsa_free( rsa ); - } - - return( ret ); -} -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * Parse a SEC1 encoded private EC key - */ -static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, - const unsigned char *key, - size_t keylen ) -{ - int ret; - int version, pubkey_done; - size_t len; - mbedtls_asn1_buf params; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - unsigned char *end2; - - /* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( version != 1 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - p += len; - - pubkey_done = 0; - if( p != end ) - { - /* - * Is 'parameters' present? - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) - { - if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || - ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( ret ); - } - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - } - - if( p != end ) - { - /* - * Is 'publickey' present? If not, or if we can't read it (eg because it - * is compressed), create it from the private key. - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) - { - end2 = p + len; - - if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( p + len != end2 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) - pubkey_done = 1; - else - { - /* - * The only acceptable failure mode of pk_get_ecpubkey() above - * is if the point format is not recognized. - */ - if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - } - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - } - - if( ! pubkey_done && - ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, - NULL, NULL ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_ECP_C */ - -/* - * Parse an unencrypted PKCS#8 encoded private key - * - * Notes: - * - * - This function does not own the key buffer. It is the - * responsibility of the caller to take care of zeroizing - * and freeing it after use. - * - * - The function is responsible for freeing the provided - * PK context on failure. - * - */ -static int pk_parse_key_pkcs8_unencrypted_der( - mbedtls_pk_context *pk, - const unsigned char* key, - size_t keylen ) -{ - int ret, version; - size_t len; - mbedtls_asn1_buf params; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - const mbedtls_pk_info_t *pk_info; - - /* - * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208) - * - * PrivateKeyInfo ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL } - * - * Version ::= INTEGER - * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - * PrivateKey ::= OCTET STRING - * - * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey - */ - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( version != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret ); - - if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( len < 1 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_RSA_C) - if( pk_alg == MBEDTLS_PK_RSA ) - { - if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 ) - { - mbedtls_pk_free( pk ); - return( ret ); - } - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) - if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH ) - { - if( ( ret = pk_use_ecparams( ¶ms, &mbedtls_pk_ec( *pk )->grp ) ) != 0 || - ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 ) - { - mbedtls_pk_free( pk ); - return( ret ); - } - } else -#endif /* MBEDTLS_ECP_C */ - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - return( 0 ); -} - -/* - * Parse an encrypted PKCS#8 encoded private key - * - * To save space, the decryption happens in-place on the given key buffer. - * Also, while this function may modify the keybuffer, it doesn't own it, - * and instead it is the responsibility of the caller to zeroize and properly - * free it after use. - * - */ -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) -static int pk_parse_key_pkcs8_encrypted_der( - mbedtls_pk_context *pk, - unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) -{ - int ret, decrypted = 0; - size_t len; - unsigned char *buf; - unsigned char *p, *end; - mbedtls_asn1_buf pbe_alg_oid, pbe_params; -#if defined(MBEDTLS_PKCS12_C) - mbedtls_cipher_type_t cipher_alg; - mbedtls_md_type_t md_alg; -#endif - - p = key; - end = p + keylen; - - if( pwdlen == 0 ) - return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); - - /* - * This function parses the EncryptedPrivateKeyInfo object (PKCS#8) - * - * EncryptedPrivateKeyInfo ::= SEQUENCE { - * encryptionAlgorithm EncryptionAlgorithmIdentifier, - * encryptedData EncryptedData - * } - * - * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * EncryptedData ::= OCTET STRING - * - * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo - * - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - buf = p; - - /* - * Decrypt EncryptedData with appropriate PBE - */ -#if defined(MBEDTLS_PKCS12_C) - if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 ) - { - if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT, - cipher_alg, md_alg, - pwd, pwdlen, p, len, buf ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - - return( ret ); - } - - decrypted = 1; - } - else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 ) - { - if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params, - MBEDTLS_PKCS12_PBE_DECRYPT, - pwd, pwdlen, - p, len, buf ) ) != 0 ) - { - return( ret ); - } - - // Best guess for password mismatch when using RC4. If first tag is - // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE - // - if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - - decrypted = 1; - } - else -#endif /* MBEDTLS_PKCS12_C */ -#if defined(MBEDTLS_PKCS5_C) - if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 ) - { - if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen, - p, len, buf ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - - return( ret ); - } - - decrypted = 1; - } - else -#endif /* MBEDTLS_PKCS5_C */ - { - ((void) pwd); - } - - if( decrypted == 0 ) - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); -} -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ - -/* - * Parse a private key - */ -int mbedtls_pk_parse_key( mbedtls_pk_context *pk, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) -{ - int ret; - const mbedtls_pk_info_t *pk_info; -#if defined(MBEDTLS_PEM_PARSE_C) - size_t len; - mbedtls_pem_context pem; -#endif - - PK_VALIDATE_RET( pk != NULL ); - if( keylen == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - PK_VALIDATE_RET( key != NULL ); - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); - -#if defined(MBEDTLS_RSA_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN RSA PRIVATE KEY-----", - "-----END RSA PRIVATE KEY-----", - key, pwd, pwdlen, &len ); - - if( ret == 0 ) - { - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ); - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || - ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), - pem.buf, pem.buflen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) - return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN EC PRIVATE KEY-----", - "-----END EC PRIVATE KEY-----", - key, pwd, pwdlen, &len ); - if( ret == 0 ) - { - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); - - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || - ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), - pem.buf, pem.buflen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) - return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); -#endif /* MBEDTLS_ECP_C */ - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN PRIVATE KEY-----", - "-----END PRIVATE KEY-----", - key, NULL, 0, &len ); - if( ret == 0 ) - { - if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, - pem.buf, pem.buflen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); - -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN ENCRYPTED PRIVATE KEY-----", - "-----END ENCRYPTED PRIVATE KEY-----", - key, NULL, 0, &len ); - if( ret == 0 ) - { - if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, - pem.buf, pem.buflen, - pwd, pwdlen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ -#else - ((void) pwd); - ((void) pwdlen); -#endif /* MBEDTLS_PEM_PARSE_C */ - - /* - * At this point we only know it's not a PEM formatted key. Could be any - * of the known DER encoded private key formats - * - * We try the different DER format parsers to see if one passes without - * error - */ -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) - { - unsigned char *key_copy; - - if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - memcpy( key_copy, key, keylen ); - - ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen, - pwd, pwdlen ); - - mbedtls_platform_zeroize( key_copy, keylen ); - mbedtls_free( key_copy ); - } - - if( ret == 0 ) - return( 0 ); - - mbedtls_pk_free( pk ); - mbedtls_pk_init( pk ); - - if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH ) - { - return( ret ); - } -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ - - if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) - return( 0 ); - - mbedtls_pk_free( pk ); - mbedtls_pk_init( pk ); - -#if defined(MBEDTLS_RSA_C) - - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ); - if( mbedtls_pk_setup( pk, pk_info ) == 0 && - pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 ) - { - return( 0 ); - } - - mbedtls_pk_free( pk ); - mbedtls_pk_init( pk ); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); - if( mbedtls_pk_setup( pk, pk_info ) == 0 && - pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), - key, keylen ) == 0 ) - { - return( 0 ); - } - mbedtls_pk_free( pk ); -#endif /* MBEDTLS_ECP_C */ - - /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't, - * it is ok to leave the PK context initialized but not - * freed: It is the caller's responsibility to call pk_init() - * before calling this function, and to call pk_free() - * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C - * isn't, this leads to mbedtls_pk_free() being called - * twice, once here and once by the caller, but this is - * also ok and in line with the mbedtls_pk_free() calls - * on failed PEM parsing attempts. */ - - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); -} - -/* - * Parse a public key - */ -int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, - const unsigned char *key, size_t keylen ) -{ - int ret; - unsigned char *p; -#if defined(MBEDTLS_RSA_C) - const mbedtls_pk_info_t *pk_info; -#endif -#if defined(MBEDTLS_PEM_PARSE_C) - size_t len; - mbedtls_pem_context pem; -#endif - - PK_VALIDATE_RET( ctx != NULL ); - if( keylen == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - PK_VALIDATE_RET( key != NULL || keylen == 0 ); - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); -#if defined(MBEDTLS_RSA_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN RSA PUBLIC KEY-----", - "-----END RSA PUBLIC KEY-----", - key, NULL, 0, &len ); - - if( ret == 0 ) - { - p = pem.buf; - if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) - return( ret ); - - if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 ) - mbedtls_pk_free( ctx ); - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - return( ret ); - } -#endif /* MBEDTLS_RSA_C */ - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN PUBLIC KEY-----", - "-----END PUBLIC KEY-----", - key, NULL, 0, &len ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - p = pem.buf; - - ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx ); - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - return( ret ); - } - mbedtls_pem_free( &pem ); -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_RSA_C) - if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) - return( ret ); - - p = (unsigned char *)key; - ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) ); - if( ret == 0 ) - { - return( ret ); - } - mbedtls_pk_free( ctx ); - if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) - { - return( ret ); - } -#endif /* MBEDTLS_RSA_C */ - p = (unsigned char *) key; - - ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_PK_PARSE_C */ diff --git a/library/pkwrite.c b/library/pkwrite.c deleted file mode 100644 index b87f81b8b7..0000000000 --- a/library/pkwrite.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Public Key layer for writing key files and structures - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_WRITE_C) - -#include "mbedtls/pk.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#endif -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_RSA_C) -/* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ -static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, - mbedtls_rsa_context *rsa ) -{ - int ret; - size_t len = 0; - mbedtls_mpi T; - - mbedtls_mpi_init( &T ); - - /* Export E */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export N */ - if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) - goto end_of_export; - len += ret; - -end_of_export: - - mbedtls_mpi_free( &T ); - if( ret < 0 ) - return( ret ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * EC public key is an EC point - */ -static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec ) -{ - int ret; - size_t len = 0; - unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; - - if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &len, buf, sizeof( buf ) ) ) != 0 ) - { - return( ret ); - } - - if( *p < start || (size_t)( *p - start ) < len ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *p -= len; - memcpy( *p, buf, len ); - - return( (int) len ); -} - -/* - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * } - */ -static int pk_write_ec_param( unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec ) -{ - int ret; - size_t len = 0; - const char *oid; - size_t oid_len; - - if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) - return( ret ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); - - return( (int) len ); -} -#endif /* MBEDTLS_ECP_C */ - -int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, - const mbedtls_pk_context *key ) -{ - int ret; - size_t len = 0; - - PK_VALIDATE_RET( p != NULL ); - PK_VALIDATE_RET( *p != NULL ); - PK_VALIDATE_RET( start != NULL ); - PK_VALIDATE_RET( key != NULL ); - -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) - MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); - else -#endif -#if defined(MBEDTLS_ECP_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) - MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); - else -#endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_OPAQUE ) - { - size_t buffer_size; - psa_key_handle_t* key_slot = (psa_key_handle_t*) key->pk_ctx; - - if ( *p < start ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - buffer_size = (size_t)( *p - start ); - if ( psa_export_public_key( *key_slot, start, buffer_size, &len ) - != PSA_SUCCESS ) - { - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - } - else - { - *p -= len; - memmove( *p, start, len ); - } - } - else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - return( (int) len ); -} - -int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char *c; - size_t len = 0, par_len = 0, oid_len; - mbedtls_pk_type_t pk_type; - const char *oid; - - PK_VALIDATE_RET( key != NULL ); - if( size == 0 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - PK_VALIDATE_RET( buf != NULL ); - - c = buf + size; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); - - if( c - buf < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - /* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ - *--c = 0; - len += 1; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); - - pk_type = mbedtls_pk_get_type( key ); -#if defined(MBEDTLS_ECP_C) - if( pk_type == MBEDTLS_PK_ECKEY ) - { - MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); - } -#endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( pk_type == MBEDTLS_PK_OPAQUE ) - { - psa_status_t status; - psa_key_type_t key_type; - psa_key_handle_t handle; - psa_ecc_curve_t curve; - - handle = *((psa_key_handle_t*) key->pk_ctx ); - - status = psa_get_key_information( handle, &key_type, - NULL /* bitsize not needed */ ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); - - curve = PSA_KEY_TYPE_GET_CURVE( key_type ); - if( curve == 0 ) - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - ret = mbedtls_psa_get_ecc_oid_from_id( curve, &oid, &oid_len ); - if( ret != 0 ) - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - /* Write EC algorithm parameters; that's akin - * to pk_write_ec_param() above. */ - MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_oid( &c, buf, - oid, oid_len ) ); - - /* The rest of the function works as for legacy EC contexts. */ - pk_type = MBEDTLS_PK_ECKEY; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if( ( ret = mbedtls_oid_get_oid_by_pk_alg( pk_type, &oid, - &oid_len ) ) != 0 ) - { - return( ret ); - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, - par_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} - -int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char *c; - size_t len = 0; - - PK_VALIDATE_RET( key != NULL ); - if( size == 0 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - PK_VALIDATE_RET( buf != NULL ); - - c = buf + size; - -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) - { - mbedtls_mpi T; /* Temporary holding the exported parameters */ - mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); - - /* - * Export the parameters one after another to avoid simultaneous copies. - */ - - mbedtls_mpi_init( &T ); - - /* Export QP */ - if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export DQ */ - if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export DP */ - if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export Q */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, - &T, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export P */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T, - NULL, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export D */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, - NULL, &T, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export E */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, - NULL, NULL, &T ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export N */ - if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, - NULL, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - end_of_export: - - mbedtls_mpi_free( &T ); - if( ret < 0 ) - return( ret ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, - buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - } - else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) - { - mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); - size_t pub_len = 0, par_len = 0; - - /* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - - /* publicKey */ - MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); - - if( c - buf < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - *--c = 0; - pub_len += 1; - - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); - - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); - len += pub_len; - - /* parameters */ - MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); - - MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); - MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); - len += par_len; - - /* privateKey: write as MPI then fix tag */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) ); - *c = MBEDTLS_ASN1_OCTET_STRING; - - /* version */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - } - else -#endif /* MBEDTLS_ECP_C */ - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - return( (int) len ); -} - -#if defined(MBEDTLS_PEM_WRITE_C) - -#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" -#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" - -#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" -#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" -#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" -#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" - -/* - * Max sizes of key per types. Shown as tag + len (+ content). - */ - -#if defined(MBEDTLS_RSA_C) -/* - * RSA public keys: - * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 - * algorithm AlgorithmIdentifier, 1 + 1 (sequence) - * + 1 + 1 + 9 (rsa oid) - * + 1 + 1 (params null) - * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) - * RSAPublicKey ::= SEQUENCE { 1 + 3 - * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 - * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 - * } - */ -#define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE - -/* - * RSA private keys: - * RSAPrivateKey ::= SEQUENCE { 1 + 3 - * version Version, 1 + 1 + 1 - * modulus INTEGER, 1 + 3 + MPI_MAX + 1 - * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 - * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 - * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) - * } - */ -#define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \ - MBEDTLS_MPI_MAX_SIZE % 2 -#define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ - + 5 * MPI_MAX_SIZE_2 - -#else /* MBEDTLS_RSA_C */ - -#define RSA_PUB_DER_MAX_BYTES 0 -#define RSA_PRV_DER_MAX_BYTES 0 - -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * EC public keys: - * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 - * algorithm AlgorithmIdentifier, 1 + 1 (sequence) - * + 1 + 1 + 7 (ec oid) - * + 1 + 1 + 9 (namedCurve oid) - * subjectPublicKey BIT STRING 1 + 2 + 1 [1] - * + 1 (point format) [1] - * + 2 * ECP_MAX (coords) [1] - * } - */ -#define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES - -/* - * EC private keys: - * ECPrivateKey ::= SEQUENCE { 1 + 2 - * version INTEGER , 1 + 1 + 1 - * privateKey OCTET STRING, 1 + 1 + ECP_MAX - * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) - * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above - * } - */ -#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES - -#else /* MBEDTLS_ECP_C */ - -#define ECP_PUB_DER_MAX_BYTES 0 -#define ECP_PRV_DER_MAX_BYTES 0 - -#endif /* MBEDTLS_ECP_C */ - -#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ - RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES -#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ - RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES - -int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char output_buf[PUB_DER_MAX_BYTES]; - size_t olen = 0; - - PK_VALIDATE_RET( key != NULL ); - PK_VALIDATE_RET( buf != NULL || size == 0 ); - - if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, - sizeof(output_buf) ) ) < 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char output_buf[PRV_DER_MAX_BYTES]; - const char *begin, *end; - size_t olen = 0; - - PK_VALIDATE_RET( key != NULL ); - PK_VALIDATE_RET( buf != NULL || size == 0 ); - - if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) - return( ret ); - -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) - { - begin = PEM_BEGIN_PRIVATE_KEY_RSA; - end = PEM_END_PRIVATE_KEY_RSA; - } - else -#endif -#if defined(MBEDTLS_ECP_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) - { - begin = PEM_BEGIN_PRIVATE_KEY_EC; - end = PEM_END_PRIVATE_KEY_EC; - } - else -#endif - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - if( ( ret = mbedtls_pem_write_buffer( begin, end, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_PK_WRITE_C */ diff --git a/library/platform.c b/library/platform.c deleted file mode 100644 index 5756159543..0000000000 --- a/library/platform.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Platform abstraction layer - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PLATFORM_C) - -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" - -/* The compile time configuration of memory allocation via the macros - * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime - * configuration via mbedtls_platform_set_calloc_free(). So, omit everything - * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ -#if defined(MBEDTLS_PLATFORM_MEMORY) && \ - !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ - defined(MBEDTLS_PLATFORM_FREE_MACRO) ) - -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -static void *platform_calloc_uninit( size_t n, size_t size ) -{ - ((void) n); - ((void) size); - return( NULL ); -} - -#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit -#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ - -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -static void platform_free_uninit( void *ptr ) -{ - ((void) ptr); -} - -#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FREE */ - -static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; -static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE; - -void * mbedtls_calloc( size_t nmemb, size_t size ) -{ - return (*mbedtls_calloc_func)( nmemb, size ); -} - -void mbedtls_free( void * ptr ) -{ - (*mbedtls_free_func)( ptr ); -} - -int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), - void (*free_func)( void * ) ) -{ - mbedtls_calloc_func = calloc_func; - mbedtls_free_func = free_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_MEMORY && - !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && - defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ - -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) -#include -int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) -{ - int ret; - va_list argp; - - va_start( argp, fmt ); - ret = mbedtls_vsnprintf( s, n, fmt, argp ); - va_end( argp ); - - return( ret ); -} -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_snprintf_uninit( char * s, size_t n, - const char * format, ... ) -{ - ((void) s); - ((void) n); - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ - -int (*mbedtls_snprintf)( char * s, size_t n, - const char * format, - ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; - -int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, - const char * format, - ... ) ) -{ - mbedtls_snprintf = snprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) -#include -int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg ) -{ - int ret; - - /* Avoid calling the invalid parameter handler by checking ourselves */ - if( s == NULL || n == 0 || fmt == NULL ) - return( -1 ); - -#if defined(_TRUNCATE) - ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg ); -#else - ret = vsnprintf( s, n, fmt, arg ); - if( ret < 0 || (size_t) ret == n ) - { - s[n-1] = '\0'; - ret = -1; - } -#endif - - return( ret ); -} -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_vsnprintf_uninit( char * s, size_t n, - const char * format, va_list arg ) -{ - ((void) s); - ((void) n); - ((void) format); - ((void) arg); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */ - -int (*mbedtls_vsnprintf)( char * s, size_t n, - const char * format, - va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF; - -int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n, - const char * format, - va_list arg ) ) -{ - mbedtls_vsnprintf = vsnprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_printf_uninit( const char *format, ... ) -{ - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ - -int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; - -int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) -{ - mbedtls_printf = printf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) -{ - ((void) stream); - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ - -int (*mbedtls_fprintf)( FILE *, const char *, ... ) = - MBEDTLS_PLATFORM_STD_FPRINTF; - -int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) -{ - mbedtls_fprintf = fprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static void platform_exit_uninit( int status ) -{ - ((void) status); -} - -#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit -#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ - -void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; - -int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) -{ - mbedtls_exit = exit_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -#if defined(MBEDTLS_HAVE_TIME) - -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) -{ - ((void) timer); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit -#endif /* !MBEDTLS_PLATFORM_STD_TIME */ - -mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; - -int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) -{ - mbedtls_time = time_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Default implementations for the platform independent seed functions use - * standard libc file functions to read from and write to a pre-defined filename - */ -int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) -{ - FILE *file; - size_t n; - - if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) - return( -1 ); - - if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) - { - fclose( file ); - mbedtls_platform_zeroize( buf, buf_len ); - return( -1 ); - } - - fclose( file ); - return( (int)n ); -} - -int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) -{ - FILE *file; - size_t n; - - if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) - return -1; - - if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) - { - fclose( file ); - return -1; - } - - fclose( file ); - return( (int)n ); -} -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) -{ - ((void) buf); - ((void) buf_len); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ - -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) -{ - ((void) buf); - ((void) buf_len); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ - -int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = - MBEDTLS_PLATFORM_STD_NV_SEED_READ; -int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = - MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; - -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), - int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) -{ - mbedtls_nv_seed_read = nv_seed_read_func; - mbedtls_nv_seed_write = nv_seed_write_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) -/* - * Placeholder platform setup that does nothing by default - */ -int mbedtls_platform_setup( mbedtls_platform_context *ctx ) -{ - (void)ctx; - - return( 0 ); -} - -/* - * Placeholder platform teardown that does nothing by default - */ -void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) -{ - (void)ctx; -} -#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ - -#endif /* MBEDTLS_PLATFORM_C */ diff --git a/library/platform_util.c b/library/platform_util.c deleted file mode 100644 index 756e22679a..0000000000 --- a/library/platform_util.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Common and shared functions used by multiple modules in the Mbed TLS - * library. - * - * Copyright (C) 2018, Arm Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * config.h, which pulls in glibc's features.h. Harmless on other platforms. - */ -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112L -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "mbedtls/platform_util.h" -#include "mbedtls/platform.h" -#include "mbedtls/threading.h" - -#include -#include - -#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) -/* - * This implementation should never be optimized out by the compiler - * - * This implementation for mbedtls_platform_zeroize() was inspired from Colin - * Percival's blog article at: - * - * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html - * - * It uses a volatile function pointer to the standard memset(). Because the - * pointer is volatile the compiler expects it to change at - * any time and will not optimize out the call that could potentially perform - * other operations on the input buffer instead of just setting it to 0. - * Nevertheless, as pointed out by davidtgoldblatt on Hacker News - * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for - * details), optimizations of the following form are still possible: - * - * if( memset_func != memset ) - * memset_func( buf, 0, len ); - * - * Note that it is extremely difficult to guarantee that - * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers - * in a portable way. For this reason, Mbed TLS also provides the configuration - * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for their - * platform and needs. - */ -static void * (* const volatile memset_func)( void *, int, size_t ) = memset; - -void mbedtls_platform_zeroize( void *buf, size_t len ) -{ - memset_func( buf, 0, len ); -} -#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -#include -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) -#include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ - -#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ -#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) -#define PLATFORM_UTIL_USE_GMTIME -#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ - -struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, - struct tm *tm_buf ) -{ -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL ); -#elif !defined(PLATFORM_UTIL_USE_GMTIME) - return( gmtime_r( tt, tm_buf ) ); -#else - struct tm *lt; - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( NULL ); -#endif /* MBEDTLS_THREADING_C */ - - lt = gmtime( tt ); - - if( lt != NULL ) - { - memcpy( tm_buf, lt, sizeof( struct tm ) ); - } - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( NULL ); -#endif /* MBEDTLS_THREADING_C */ - - return( ( lt == NULL ) ? NULL : tm_buf ); -#endif /* _WIN32 && !EFIX64 && !EFI32 */ -} -#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ diff --git a/library/poly1305.c b/library/poly1305.c deleted file mode 100644 index 2b56c5f7ef..0000000000 --- a/library/poly1305.c +++ /dev/null @@ -1,559 +0,0 @@ -/** - * \file poly1305.c - * - * \brief Poly1305 authentication algorithm. - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_POLY1305_C) - -#include "mbedtls/poly1305.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_POLY1305_ALT) - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Parameter validation macros */ -#define POLY1305_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ) -#define POLY1305_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define POLY1305_BLOCK_SIZE_BYTES ( 16U ) - -#define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t) (data)[offset] \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ - ) - -/* - * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier. - * However we provided an alternative for platforms without such a multiplier. - */ -#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) -static uint64_t mul64( uint32_t a, uint32_t b ) -{ - /* a = al + 2**16 ah, b = bl + 2**16 bh */ - const uint16_t al = (uint16_t) a; - const uint16_t bl = (uint16_t) b; - const uint16_t ah = a >> 16; - const uint16_t bh = b >> 16; - - /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */ - const uint32_t lo = (uint32_t) al * bl; - const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh; - const uint32_t hi = (uint32_t) ah * bh; - - return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) ); -} -#else -static inline uint64_t mul64( uint32_t a, uint32_t b ) -{ - return( (uint64_t) a * b ); -} -#endif - - -/** - * \brief Process blocks with Poly1305. - * - * \param ctx The Poly1305 context. - * \param nblocks Number of blocks to process. Note that this - * function only processes full blocks. - * \param input Buffer containing the input block(s). - * \param needs_padding Set to 0 if the padding bit has already been - * applied to the input data before calling this - * function. Otherwise, set this parameter to 1. - */ -static void poly1305_process( mbedtls_poly1305_context *ctx, - size_t nblocks, - const unsigned char *input, - uint32_t needs_padding ) -{ - uint64_t d0, d1, d2, d3; - uint32_t acc0, acc1, acc2, acc3, acc4; - uint32_t r0, r1, r2, r3; - uint32_t rs1, rs2, rs3; - size_t offset = 0U; - size_t i; - - r0 = ctx->r[0]; - r1 = ctx->r[1]; - r2 = ctx->r[2]; - r3 = ctx->r[3]; - - rs1 = r1 + ( r1 >> 2U ); - rs2 = r2 + ( r2 >> 2U ); - rs3 = r3 + ( r3 >> 2U ); - - acc0 = ctx->acc[0]; - acc1 = ctx->acc[1]; - acc2 = ctx->acc[2]; - acc3 = ctx->acc[3]; - acc4 = ctx->acc[4]; - - /* Process full blocks */ - for( i = 0U; i < nblocks; i++ ) - { - /* The input block is treated as a 128-bit little-endian integer */ - d0 = BYTES_TO_U32_LE( input, offset + 0 ); - d1 = BYTES_TO_U32_LE( input, offset + 4 ); - d2 = BYTES_TO_U32_LE( input, offset + 8 ); - d3 = BYTES_TO_U32_LE( input, offset + 12 ); - - /* Compute: acc += (padded) block as a 130-bit integer */ - d0 += (uint64_t) acc0; - d1 += (uint64_t) acc1 + ( d0 >> 32U ); - d2 += (uint64_t) acc2 + ( d1 >> 32U ); - d3 += (uint64_t) acc3 + ( d2 >> 32U ); - acc0 = (uint32_t) d0; - acc1 = (uint32_t) d1; - acc2 = (uint32_t) d2; - acc3 = (uint32_t) d3; - acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding; - - /* Compute: acc *= r */ - d0 = mul64( acc0, r0 ) + - mul64( acc1, rs3 ) + - mul64( acc2, rs2 ) + - mul64( acc3, rs1 ); - d1 = mul64( acc0, r1 ) + - mul64( acc1, r0 ) + - mul64( acc2, rs3 ) + - mul64( acc3, rs2 ) + - mul64( acc4, rs1 ); - d2 = mul64( acc0, r2 ) + - mul64( acc1, r1 ) + - mul64( acc2, r0 ) + - mul64( acc3, rs3 ) + - mul64( acc4, rs2 ); - d3 = mul64( acc0, r3 ) + - mul64( acc1, r2 ) + - mul64( acc2, r1 ) + - mul64( acc3, r0 ) + - mul64( acc4, rs3 ); - acc4 *= r0; - - /* Compute: acc %= (2^130 - 5) (partial remainder) */ - d1 += ( d0 >> 32 ); - d2 += ( d1 >> 32 ); - d3 += ( d2 >> 32 ); - acc0 = (uint32_t) d0; - acc1 = (uint32_t) d1; - acc2 = (uint32_t) d2; - acc3 = (uint32_t) d3; - acc4 = (uint32_t) ( d3 >> 32 ) + acc4; - - d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU ); - acc4 &= 3U; - acc0 = (uint32_t) d0; - d0 = (uint64_t) acc1 + ( d0 >> 32U ); - acc1 = (uint32_t) d0; - d0 = (uint64_t) acc2 + ( d0 >> 32U ); - acc2 = (uint32_t) d0; - d0 = (uint64_t) acc3 + ( d0 >> 32U ); - acc3 = (uint32_t) d0; - d0 = (uint64_t) acc4 + ( d0 >> 32U ); - acc4 = (uint32_t) d0; - - offset += POLY1305_BLOCK_SIZE_BYTES; - } - - ctx->acc[0] = acc0; - ctx->acc[1] = acc1; - ctx->acc[2] = acc2; - ctx->acc[3] = acc3; - ctx->acc[4] = acc4; -} - -/** - * \brief Compute the Poly1305 MAC - * - * \param ctx The Poly1305 context. - * \param mac The buffer to where the MAC is written. Must be - * big enough to contain the 16-byte MAC. - */ -static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx, - unsigned char mac[16] ) -{ - uint64_t d; - uint32_t g0, g1, g2, g3, g4; - uint32_t acc0, acc1, acc2, acc3, acc4; - uint32_t mask; - uint32_t mask_inv; - - acc0 = ctx->acc[0]; - acc1 = ctx->acc[1]; - acc2 = ctx->acc[2]; - acc3 = ctx->acc[3]; - acc4 = ctx->acc[4]; - - /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5. - * We do this by calculating acc - (2^130 - 5), then checking if - * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5) - */ - - /* Calculate acc + -(2^130 - 5) */ - d = ( (uint64_t) acc0 + 5U ); - g0 = (uint32_t) d; - d = ( (uint64_t) acc1 + ( d >> 32 ) ); - g1 = (uint32_t) d; - d = ( (uint64_t) acc2 + ( d >> 32 ) ); - g2 = (uint32_t) d; - d = ( (uint64_t) acc3 + ( d >> 32 ) ); - g3 = (uint32_t) d; - g4 = acc4 + (uint32_t) ( d >> 32U ); - - /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */ - mask = (uint32_t) 0U - ( g4 >> 2U ); - mask_inv = ~mask; - - /* If 131st bit is set then acc=g, otherwise, acc is unmodified */ - acc0 = ( acc0 & mask_inv ) | ( g0 & mask ); - acc1 = ( acc1 & mask_inv ) | ( g1 & mask ); - acc2 = ( acc2 & mask_inv ) | ( g2 & mask ); - acc3 = ( acc3 & mask_inv ) | ( g3 & mask ); - - /* Add 's' */ - d = (uint64_t) acc0 + ctx->s[0]; - acc0 = (uint32_t) d; - d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U ); - acc1 = (uint32_t) d; - d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U ); - acc2 = (uint32_t) d; - acc3 += ctx->s[3] + (uint32_t) ( d >> 32U ); - - /* Compute MAC (128 least significant bits of the accumulator) */ - mac[ 0] = (unsigned char)( acc0 ); - mac[ 1] = (unsigned char)( acc0 >> 8 ); - mac[ 2] = (unsigned char)( acc0 >> 16 ); - mac[ 3] = (unsigned char)( acc0 >> 24 ); - mac[ 4] = (unsigned char)( acc1 ); - mac[ 5] = (unsigned char)( acc1 >> 8 ); - mac[ 6] = (unsigned char)( acc1 >> 16 ); - mac[ 7] = (unsigned char)( acc1 >> 24 ); - mac[ 8] = (unsigned char)( acc2 ); - mac[ 9] = (unsigned char)( acc2 >> 8 ); - mac[10] = (unsigned char)( acc2 >> 16 ); - mac[11] = (unsigned char)( acc2 >> 24 ); - mac[12] = (unsigned char)( acc3 ); - mac[13] = (unsigned char)( acc3 >> 8 ); - mac[14] = (unsigned char)( acc3 >> 16 ); - mac[15] = (unsigned char)( acc3 >> 24 ); -} - -void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ) -{ - POLY1305_VALIDATE( ctx != NULL ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); -} - -void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); -} - -int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, - const unsigned char key[32] ) -{ - POLY1305_VALIDATE_RET( ctx != NULL ); - POLY1305_VALIDATE_RET( key != NULL ); - - /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */ - ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU; - ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU; - ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU; - ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU; - - ctx->s[0] = BYTES_TO_U32_LE( key, 16 ); - ctx->s[1] = BYTES_TO_U32_LE( key, 20 ); - ctx->s[2] = BYTES_TO_U32_LE( key, 24 ); - ctx->s[3] = BYTES_TO_U32_LE( key, 28 ); - - /* Initial accumulator state */ - ctx->acc[0] = 0U; - ctx->acc[1] = 0U; - ctx->acc[2] = 0U; - ctx->acc[3] = 0U; - ctx->acc[4] = 0U; - - /* Queue initially empty */ - mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) ); - ctx->queue_len = 0U; - - return( 0 ); -} - -int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - size_t offset = 0U; - size_t remaining = ilen; - size_t queue_free_len; - size_t nblocks; - POLY1305_VALIDATE_RET( ctx != NULL ); - POLY1305_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) ) - { - queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); - - if( ilen < queue_free_len ) - { - /* Not enough data to complete the block. - * Store this data with the other leftovers. - */ - memcpy( &ctx->queue[ctx->queue_len], - input, - ilen ); - - ctx->queue_len += ilen; - - remaining = 0U; - } - else - { - /* Enough data to produce a complete block */ - memcpy( &ctx->queue[ctx->queue_len], - input, - queue_free_len ); - - ctx->queue_len = 0U; - - poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */ - - offset += queue_free_len; - remaining -= queue_free_len; - } - } - - if( remaining >= POLY1305_BLOCK_SIZE_BYTES ) - { - nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES; - - poly1305_process( ctx, nblocks, &input[offset], 1U ); - - offset += nblocks * POLY1305_BLOCK_SIZE_BYTES; - remaining %= POLY1305_BLOCK_SIZE_BYTES; - } - - if( remaining > 0U ) - { - /* Store partial block */ - ctx->queue_len = remaining; - memcpy( ctx->queue, &input[offset], remaining ); - } - - return( 0 ); -} - -int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, - unsigned char mac[16] ) -{ - POLY1305_VALIDATE_RET( ctx != NULL ); - POLY1305_VALIDATE_RET( mac != NULL ); - - /* Process any leftover data */ - if( ctx->queue_len > 0U ) - { - /* Add padding bit */ - ctx->queue[ctx->queue_len] = 1U; - ctx->queue_len++; - - /* Pad with zeroes */ - memset( &ctx->queue[ctx->queue_len], - 0, - POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); - - poly1305_process( ctx, 1U, /* Process 1 block */ - ctx->queue, 0U ); /* Already padded above */ - } - - poly1305_compute_mac( ctx, mac ); - - return( 0 ); -} - -int mbedtls_poly1305_mac( const unsigned char key[32], - const unsigned char *input, - size_t ilen, - unsigned char mac[16] ) -{ - mbedtls_poly1305_context ctx; - int ret; - POLY1305_VALIDATE_RET( key != NULL ); - POLY1305_VALIDATE_RET( mac != NULL ); - POLY1305_VALIDATE_RET( ilen == 0 || input != NULL ); - - mbedtls_poly1305_init( &ctx ); - - ret = mbedtls_poly1305_starts( &ctx, key ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_poly1305_update( &ctx, input, ilen ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_poly1305_finish( &ctx, mac ); - -cleanup: - mbedtls_poly1305_free( &ctx ); - return( ret ); -} - -#endif /* MBEDTLS_POLY1305_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_keys[2][32] = -{ - { - 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, - 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8, - 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, - 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b - }, - { - 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, - 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0, - 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, - 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0 - } -}; - -static const unsigned char test_data[2][127] = -{ - { - 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f, - 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f, - 0x75, 0x70 - }, - { - 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, - 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, - 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20, - 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, - 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, - 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c, - 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, - 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, - 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20, - 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75, - 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e - } -}; - -static const size_t test_data_len[2] = -{ - 34U, - 127U -}; - -static const unsigned char test_mac[2][16] = -{ - { - 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, - 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9 - }, - { - 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, - 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62 - } -}; - -#define ASSERT( cond, args ) \ - do \ - { \ - if( ! ( cond ) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf args; \ - \ - return( -1 ); \ - } \ - } \ - while( 0 ) - -int mbedtls_poly1305_self_test( int verbose ) -{ - unsigned char mac[16]; - unsigned i; - int ret; - - for( i = 0U; i < 2U; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " Poly1305 test %u ", i ); - - ret = mbedtls_poly1305_mac( test_keys[i], - test_data[i], - test_data_len[i], - mac ); - ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); - - ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_POLY1305_C */ diff --git a/library/ripemd160.c b/library/ripemd160.c deleted file mode 100644 index 0791ae4cc9..0000000000 --- a/library/ripemd160.c +++ /dev/null @@ -1,559 +0,0 @@ -/* - * RIPE MD-160 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * The RIPEMD-160 algorithm was designed by RIPE in 1996 - * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html - * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_RIPEMD160_C) - -#include "mbedtls/ripemd160.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_RIPEMD160_ALT) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) ); -} - -void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) ); -} - -void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, - const mbedtls_ripemd160_context *src ) -{ - *dst = *src; -} - -/* - * RIPEMD-160 context setup - */ -int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) -{ - mbedtls_ripemd160_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) -/* - * Process one block - */ -int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, - const unsigned char data[64] ) -{ - uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); - - A = Ap = ctx->state[0]; - B = Bp = ctx->state[1]; - C = Cp = ctx->state[2]; - D = Dp = ctx->state[3]; - E = Ep = ctx->state[4]; - -#define F1( x, y, z ) ( (x) ^ (y) ^ (z) ) -#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) -#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) ) -#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) ) -#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) ) - -#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) ) - -#define P( a, b, c, d, e, r, s, f, k ) \ - do \ - { \ - (a) += f( (b), (c), (d) ) + X[r] + (k); \ - (a) = S( (a), (s) ) + (e); \ - (c) = S( (c), 10 ); \ - } while( 0 ) - -#define P2( a, b, c, d, e, r, s, rp, sp ) \ - do \ - { \ - P( (a), (b), (c), (d), (e), (r), (s), F, K ); \ - P( a ## p, b ## p, c ## p, d ## p, e ## p, \ - (rp), (sp), Fp, Kp ); \ - } while( 0 ) - -#define F F1 -#define K 0x00000000 -#define Fp F5 -#define Kp 0x50A28BE6 - P2( A, B, C, D, E, 0, 11, 5, 8 ); - P2( E, A, B, C, D, 1, 14, 14, 9 ); - P2( D, E, A, B, C, 2, 15, 7, 9 ); - P2( C, D, E, A, B, 3, 12, 0, 11 ); - P2( B, C, D, E, A, 4, 5, 9, 13 ); - P2( A, B, C, D, E, 5, 8, 2, 15 ); - P2( E, A, B, C, D, 6, 7, 11, 15 ); - P2( D, E, A, B, C, 7, 9, 4, 5 ); - P2( C, D, E, A, B, 8, 11, 13, 7 ); - P2( B, C, D, E, A, 9, 13, 6, 7 ); - P2( A, B, C, D, E, 10, 14, 15, 8 ); - P2( E, A, B, C, D, 11, 15, 8, 11 ); - P2( D, E, A, B, C, 12, 6, 1, 14 ); - P2( C, D, E, A, B, 13, 7, 10, 14 ); - P2( B, C, D, E, A, 14, 9, 3, 12 ); - P2( A, B, C, D, E, 15, 8, 12, 6 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F2 -#define K 0x5A827999 -#define Fp F4 -#define Kp 0x5C4DD124 - P2( E, A, B, C, D, 7, 7, 6, 9 ); - P2( D, E, A, B, C, 4, 6, 11, 13 ); - P2( C, D, E, A, B, 13, 8, 3, 15 ); - P2( B, C, D, E, A, 1, 13, 7, 7 ); - P2( A, B, C, D, E, 10, 11, 0, 12 ); - P2( E, A, B, C, D, 6, 9, 13, 8 ); - P2( D, E, A, B, C, 15, 7, 5, 9 ); - P2( C, D, E, A, B, 3, 15, 10, 11 ); - P2( B, C, D, E, A, 12, 7, 14, 7 ); - P2( A, B, C, D, E, 0, 12, 15, 7 ); - P2( E, A, B, C, D, 9, 15, 8, 12 ); - P2( D, E, A, B, C, 5, 9, 12, 7 ); - P2( C, D, E, A, B, 2, 11, 4, 6 ); - P2( B, C, D, E, A, 14, 7, 9, 15 ); - P2( A, B, C, D, E, 11, 13, 1, 13 ); - P2( E, A, B, C, D, 8, 12, 2, 11 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F3 -#define K 0x6ED9EBA1 -#define Fp F3 -#define Kp 0x6D703EF3 - P2( D, E, A, B, C, 3, 11, 15, 9 ); - P2( C, D, E, A, B, 10, 13, 5, 7 ); - P2( B, C, D, E, A, 14, 6, 1, 15 ); - P2( A, B, C, D, E, 4, 7, 3, 11 ); - P2( E, A, B, C, D, 9, 14, 7, 8 ); - P2( D, E, A, B, C, 15, 9, 14, 6 ); - P2( C, D, E, A, B, 8, 13, 6, 6 ); - P2( B, C, D, E, A, 1, 15, 9, 14 ); - P2( A, B, C, D, E, 2, 14, 11, 12 ); - P2( E, A, B, C, D, 7, 8, 8, 13 ); - P2( D, E, A, B, C, 0, 13, 12, 5 ); - P2( C, D, E, A, B, 6, 6, 2, 14 ); - P2( B, C, D, E, A, 13, 5, 10, 13 ); - P2( A, B, C, D, E, 11, 12, 0, 13 ); - P2( E, A, B, C, D, 5, 7, 4, 7 ); - P2( D, E, A, B, C, 12, 5, 13, 5 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F4 -#define K 0x8F1BBCDC -#define Fp F2 -#define Kp 0x7A6D76E9 - P2( C, D, E, A, B, 1, 11, 8, 15 ); - P2( B, C, D, E, A, 9, 12, 6, 5 ); - P2( A, B, C, D, E, 11, 14, 4, 8 ); - P2( E, A, B, C, D, 10, 15, 1, 11 ); - P2( D, E, A, B, C, 0, 14, 3, 14 ); - P2( C, D, E, A, B, 8, 15, 11, 14 ); - P2( B, C, D, E, A, 12, 9, 15, 6 ); - P2( A, B, C, D, E, 4, 8, 0, 14 ); - P2( E, A, B, C, D, 13, 9, 5, 6 ); - P2( D, E, A, B, C, 3, 14, 12, 9 ); - P2( C, D, E, A, B, 7, 5, 2, 12 ); - P2( B, C, D, E, A, 15, 6, 13, 9 ); - P2( A, B, C, D, E, 14, 8, 9, 12 ); - P2( E, A, B, C, D, 5, 6, 7, 5 ); - P2( D, E, A, B, C, 6, 5, 10, 15 ); - P2( C, D, E, A, B, 2, 12, 14, 8 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F5 -#define K 0xA953FD4E -#define Fp F1 -#define Kp 0x00000000 - P2( B, C, D, E, A, 4, 9, 12, 8 ); - P2( A, B, C, D, E, 0, 15, 15, 5 ); - P2( E, A, B, C, D, 5, 5, 10, 12 ); - P2( D, E, A, B, C, 9, 11, 4, 9 ); - P2( C, D, E, A, B, 7, 6, 1, 12 ); - P2( B, C, D, E, A, 12, 8, 5, 5 ); - P2( A, B, C, D, E, 2, 13, 8, 14 ); - P2( E, A, B, C, D, 10, 12, 7, 6 ); - P2( D, E, A, B, C, 14, 5, 6, 8 ); - P2( C, D, E, A, B, 1, 12, 2, 13 ); - P2( B, C, D, E, A, 3, 13, 13, 6 ); - P2( A, B, C, D, E, 8, 14, 14, 5 ); - P2( E, A, B, C, D, 11, 11, 0, 15 ); - P2( D, E, A, B, C, 6, 8, 3, 13 ); - P2( C, D, E, A, B, 15, 5, 9, 11 ); - P2( B, C, D, E, A, 13, 6, 11, 11 ); -#undef F -#undef K -#undef Fp -#undef Kp - - C = ctx->state[1] + C + Dp; - ctx->state[1] = ctx->state[2] + D + Ep; - ctx->state[2] = ctx->state[3] + E + Ap; - ctx->state[3] = ctx->state[4] + A + Bp; - ctx->state[4] = ctx->state[0] + B + Cp; - ctx->state[0] = C; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_ripemd160_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ - -/* - * RIPEMD-160 process buffer - */ -int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), input, ilen ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_ripemd160_update_ret( ctx, input, ilen ); -} -#endif - -static const unsigned char ripemd160_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * RIPEMD-160 final digest - */ -int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, - unsigned char output[20] ) -{ - int ret; - uint32_t last, padn; - uint32_t high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 ); - if( ret != 0 ) - return( ret ); - - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - PUT_UINT32_LE( ctx->state[4], output, 16 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, - unsigned char output[20] ) -{ - mbedtls_ripemd160_finish_ret( ctx, output ); -} -#endif - -#endif /* ! MBEDTLS_RIPEMD160_ALT */ - -/* - * output = RIPEMD-160( input buffer ) - */ -int mbedtls_ripemd160_ret( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - int ret; - mbedtls_ripemd160_context ctx; - - mbedtls_ripemd160_init( &ctx ); - - if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_ripemd160_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - mbedtls_ripemd160_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * Test vectors from the RIPEMD-160 paper and - * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC - */ -#define TESTS 8 -static const unsigned char ripemd160_test_str[TESTS][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" }, -}; - -static const size_t ripemd160_test_strlen[TESTS] = -{ - 0, 1, 3, 14, 26, 56, 62, 80 -}; - -static const unsigned char ripemd160_test_md[TESTS][20] = -{ - { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, - 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, - { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, - 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, - { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, - 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, - { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, - 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, - { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, - 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, - { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, - 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, - { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, - 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, - { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, - 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, -}; - -/* - * Checkup routine - */ -int mbedtls_ripemd160_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char output[20]; - - memset( output, 0, sizeof output ); - - for( i = 0; i < TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 ); - - ret = mbedtls_ripemd160_ret( ripemd160_test_str[i], - ripemd160_test_strlen[i], output ); - if( ret != 0 ) - goto fail; - - if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_RIPEMD160_C */ diff --git a/library/rsa.c b/library/rsa.c deleted file mode 100644 index a35af44746..0000000000 --- a/library/rsa.c +++ /dev/null @@ -1,2729 +0,0 @@ -/* - * The RSA public-key cryptosystem - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * The following sources were referenced in the design of this implementation - * of the RSA algorithm: - * - * [1] A method for obtaining digital signatures and public-key cryptosystems - * R Rivest, A Shamir, and L Adleman - * http://people.csail.mit.edu/rivest/pubs.html#RSA78 - * - * [2] Handbook of Applied Cryptography - 1997, Chapter 8 - * Menezes, van Oorschot and Vanstone - * - * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks - * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and - * Stefan Mangard - * https://arxiv.org/abs/1702.08719v2 - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_RSA_C) - -#include "mbedtls/rsa.h" -#include "mbedtls/rsa_internal.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PKCS1_V21) -#include "mbedtls/md.h" -#endif - -#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) -#include -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if !defined(MBEDTLS_RSA_ALT) - -/* Parameter validation macros */ -#define RSA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) -#define RSA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_PKCS1_V15) -/* constant-time buffer comparison */ -static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - const unsigned char *A = (const unsigned char *) a; - const unsigned char *B = (const unsigned char *) b; - unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - diff |= A[i] ^ B[i]; - - return( diff ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -int mbedtls_rsa_import( mbedtls_rsa_context *ctx, - const mbedtls_mpi *N, - const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *E ) -{ - int ret; - RSA_VALIDATE_RET( ctx != NULL ); - - if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) || - ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) || - ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) || - ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) || - ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } - - if( N != NULL ) - ctx->len = mbedtls_mpi_size( &ctx->N ); - - return( 0 ); -} - -int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, - unsigned char const *N, size_t N_len, - unsigned char const *P, size_t P_len, - unsigned char const *Q, size_t Q_len, - unsigned char const *D, size_t D_len, - unsigned char const *E, size_t E_len ) -{ - int ret = 0; - RSA_VALIDATE_RET( ctx != NULL ); - - if( N != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) ); - ctx->len = mbedtls_mpi_size( &ctx->N ); - } - - if( P != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) ); - - if( Q != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) ); - - if( D != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) ); - - if( E != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) ); - -cleanup: - - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - - return( 0 ); -} - -/* - * Checks whether the context fields are set in such a way - * that the RSA primitives will be able to execute without error. - * It does *not* make guarantees for consistency of the parameters. - */ -static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv, - int blinding_needed ) -{ -#if !defined(MBEDTLS_RSA_NO_CRT) - /* blinding_needed is only used for NO_CRT to decide whether - * P,Q need to be present or not. */ - ((void) blinding_needed); -#endif - - if( ctx->len != mbedtls_mpi_size( &ctx->N ) || - ctx->len > MBEDTLS_MPI_MAX_SIZE ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - /* - * 1. Modular exponentiation needs positive, odd moduli. - */ - - /* Modular exponentiation wrt. N is always used for - * RSA public key operations. */ - if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 || - mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Modular exponentiation for P and Q is only - * used for private key operations and if CRT - * is used. */ - if( is_priv && - ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || - mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 || - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 || - mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif /* !MBEDTLS_RSA_NO_CRT */ - - /* - * 2. Exponents must be positive - */ - - /* Always need E for public key operations */ - if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_RSA_NO_CRT) - /* For private key operations, use D or DP & DQ - * as (unblinded) exponents. */ - if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); -#else - if( is_priv && - ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 || - mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Blinding shouldn't make exponents negative either, - * so check that P, Q >= 1 if that hasn't yet been - * done as part of 1. */ -#if defined(MBEDTLS_RSA_NO_CRT) - if( is_priv && blinding_needed && - ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif - - /* It wouldn't lead to an error if it wasn't satisfied, - * but check for QP >= 1 nonetheless. */ -#if !defined(MBEDTLS_RSA_NO_CRT) - if( is_priv && - mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif - - return( 0 ); -} - -int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) -{ - int ret = 0; - int have_N, have_P, have_Q, have_D, have_E; - int n_missing, pq_missing, d_missing, is_pub, is_priv; - - RSA_VALIDATE_RET( ctx != NULL ); - - have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 ); - have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 ); - have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 ); - have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); - have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); - - /* - * Check whether provided parameters are enough - * to deduce all others. The following incomplete - * parameter sets for private keys are supported: - * - * (1) P, Q missing. - * (2) D and potentially N missing. - * - */ - - n_missing = have_P && have_Q && have_D && have_E; - pq_missing = have_N && !have_P && !have_Q && have_D && have_E; - d_missing = have_P && have_Q && !have_D && have_E; - is_pub = have_N && !have_P && !have_Q && !have_D && have_E; - - /* These three alternatives are mutually exclusive */ - is_priv = n_missing || pq_missing || d_missing; - - if( !is_priv && !is_pub ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Step 1: Deduce N if P, Q are provided. - */ - - if( !have_N && have_P && have_Q ) - { - if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, - &ctx->Q ) ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } - - ctx->len = mbedtls_mpi_size( &ctx->N ); - } - - /* - * Step 2: Deduce and verify all remaining core parameters. - */ - - if( pq_missing ) - { - ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D, - &ctx->P, &ctx->Q ); - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - - } - else if( d_missing ) - { - if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P, - &ctx->Q, - &ctx->E, - &ctx->D ) ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } - } - - /* - * Step 3: Deduce all additional parameters specific - * to our current RSA implementation. - */ - -#if !defined(MBEDTLS_RSA_NO_CRT) - if( is_priv ) - { - ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP ); - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* - * Step 3: Basic sanity checks - */ - - return( rsa_check_context( ctx, is_priv, 1 ) ); -} - -int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, - unsigned char *N, size_t N_len, - unsigned char *P, size_t P_len, - unsigned char *Q, size_t Q_len, - unsigned char *D, size_t D_len, - unsigned char *E, size_t E_len ) -{ - int ret = 0; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; - - if( !is_priv ) - { - /* If we're trying to export private parameters for a public key, - * something must be wrong. */ - if( P != NULL || Q != NULL || D != NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - } - - if( N != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) ); - - if( P != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) ); - - if( Q != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) ); - - if( D != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) ); - - if( E != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) ); - -cleanup: - - return( ret ); -} - -int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, - mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, - mbedtls_mpi *D, mbedtls_mpi *E ) -{ - int ret; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; - - if( !is_priv ) - { - /* If we're trying to export private parameters for a public key, - * something must be wrong. */ - if( P != NULL || Q != NULL || D != NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - } - - /* Export all requested core parameters. */ - - if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) || - ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) || - ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) || - ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) || - ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Export CRT parameters - * This must also be implemented if CRT is not used, for being able to - * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt - * can be used in this case. - */ -int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, - mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ) -{ - int ret; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; - - if( !is_priv ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Export all requested blinding parameters. */ - if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) || - ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) || - ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } -#else - if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, - DP, DQ, QP ) ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } -#endif - - return( 0 ); -} - -/* - * Initialize an RSA context - */ -void mbedtls_rsa_init( mbedtls_rsa_context *ctx, - int padding, - int hash_id ) -{ - RSA_VALIDATE( ctx != NULL ); - RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || - padding == MBEDTLS_RSA_PKCS_V21 ); - - memset( ctx, 0, sizeof( mbedtls_rsa_context ) ); - - mbedtls_rsa_set_padding( ctx, padding, hash_id ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif -} - -/* - * Set padding for an existing RSA context - */ -void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, - int hash_id ) -{ - RSA_VALIDATE( ctx != NULL ); - RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || - padding == MBEDTLS_RSA_PKCS_V21 ); - - ctx->padding = padding; - ctx->hash_id = hash_id; -} - -/* - * Get length in bytes of RSA modulus - */ - -size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ) -{ - return( ctx->len ); -} - - -#if defined(MBEDTLS_GENPRIME) - -/* - * Generate an RSA keypair - * - * This generation method follows the RSA key pair generation procedure of - * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072. - */ -int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - unsigned int nbits, int exponent ) -{ - int ret; - mbedtls_mpi H, G, L; - int prime_quality = 0; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( f_rng != NULL ); - - if( nbits < 128 || exponent < 3 || nbits % 2 != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * If the modulus is 1024 bit long or shorter, then the security strength of - * the RSA algorithm is less than or equal to 80 bits and therefore an error - * rate of 2^-80 is sufficient. - */ - if( nbits > 1024 ) - prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR; - - mbedtls_mpi_init( &H ); - mbedtls_mpi_init( &G ); - mbedtls_mpi_init( &L ); - - /* - * find primes P and Q with Q < P so that: - * 1. |P-Q| > 2^( nbits / 2 - 100 ) - * 2. GCD( E, (P-1)*(Q-1) ) == 1 - * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 ) - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) ); - - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, - prime_quality, f_rng, p_rng ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, - prime_quality, f_rng, p_rng ) ); - - /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) ); - if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) ) - continue; - - /* not required by any standards, but some users rely on the fact that P > Q */ - if( H.s < 0 ) - mbedtls_mpi_swap( &ctx->P, &ctx->Q ); - - /* Temporarily replace P,Q by P-1, Q-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) ); - - /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); - if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) - continue; - - /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) ); - - if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a)) - continue; - - break; - } - while( 1 ); - - /* Restore P,Q */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); - - ctx->len = mbedtls_mpi_size( &ctx->N ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* - * DP = D mod (P - 1) - * DQ = D mod (Q - 1) - * QP = Q^-1 mod P - */ - MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP ) ); -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Double-check */ - MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) ); - -cleanup: - - mbedtls_mpi_free( &H ); - mbedtls_mpi_free( &G ); - mbedtls_mpi_free( &L ); - - if( ret != 0 ) - { - mbedtls_rsa_free( ctx ); - return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret ); - } - - return( 0 ); -} - -#endif /* MBEDTLS_GENPRIME */ - -/* - * Check a public RSA key - */ -int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - - if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - - if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 || - mbedtls_mpi_bitlen( &ctx->E ) < 2 || - mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - return( 0 ); -} - -/* - * Check for the consistency of all fields in an RSA private key context - */ -int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - - if( mbedtls_rsa_check_pubkey( ctx ) != 0 || - rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q, - &ctx->D, &ctx->E, NULL, NULL ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } -#endif - - return( 0 ); -} - -/* - * Check if contexts holding a public and private key match - */ -int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, - const mbedtls_rsa_context *prv ) -{ - RSA_VALIDATE_RET( pub != NULL ); - RSA_VALIDATE_RET( prv != NULL ); - - if( mbedtls_rsa_check_pubkey( pub ) != 0 || - mbedtls_rsa_check_privkey( prv ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 || - mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - return( 0 ); -} - -/* - * Do an RSA public key operation - */ -int mbedtls_rsa_public( mbedtls_rsa_context *ctx, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t olen; - mbedtls_mpi T; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( output != NULL ); - - if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &T ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); - - if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) - { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - olen = ctx->len; - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - mbedtls_mpi_free( &T ); - - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret ); - - return( 0 ); -} - -/* - * Generate or update blinding values, see section 10 of: - * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, - * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer - * Berlin Heidelberg, 1996. p. 104-113. - */ -static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret, count = 0; - - if( ctx->Vf.p != NULL ) - { - /* We already have blinding values, just update them by squaring */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); - - goto cleanup; - } - - /* Unblinding value: Vf = random number, invertible mod N */ - do { - if( count++ > 10 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); - } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); - - /* Blinding value: Vi = Vf^(-e) mod N */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); - - -cleanup: - return( ret ); -} - -/* - * Exponent blinding supposed to prevent side-channel attacks using multiple - * traces of measurements to recover the RSA key. The more collisions are there, - * the more bits of the key can be recovered. See [3]. - * - * Collecting n collisions with m bit long blinding value requires 2^(m-m/n) - * observations on avarage. - * - * For example with 28 byte blinding to achieve 2 collisions the adversary has - * to make 2^112 observations on avarage. - * - * (With the currently (as of 2017 April) known best algorithms breaking 2048 - * bit RSA requires approximately as much time as trying out 2^112 random keys. - * Thus in this sense with 28 byte blinding the security is not reduced by - * side-channel attacks like the one in [3]) - * - * This countermeasure does not help if the key recovery is possible with a - * single trace. - */ -#define RSA_EXPONENT_BLINDING 28 - -/* - * Do an RSA private key operation - */ -int mbedtls_rsa_private( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t olen; - - /* Temporary holding the result */ - mbedtls_mpi T; - - /* Temporaries holding P-1, Q-1 and the - * exponent blinding factor, respectively. */ - mbedtls_mpi P1, Q1, R; - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Temporaries holding the results mod p resp. mod q. */ - mbedtls_mpi TP, TQ; - - /* Temporaries holding the blinded exponents for - * the mod p resp. mod q computation (if used). */ - mbedtls_mpi DP_blind, DQ_blind; - - /* Pointers to actual exponents to be used - either the unblinded - * or the blinded ones, depending on the presence of a PRNG. */ - mbedtls_mpi *DP = &ctx->DP; - mbedtls_mpi *DQ = &ctx->DQ; -#else - /* Temporary holding the blinded exponent (if used). */ - mbedtls_mpi D_blind; - - /* Pointer to actual exponent to be used - either the unblinded - * or the blinded one, depending on the presence of a PRNG. */ - mbedtls_mpi *D = &ctx->D; -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Temporaries holding the initial input and the double - * checked result; should be the same in the end. */ - mbedtls_mpi I, C; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( output != NULL ); - - if( rsa_check_context( ctx, 1 /* private key checks */, - f_rng != NULL /* blinding y/n */ ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - /* MPI Initialization */ - mbedtls_mpi_init( &T ); - - mbedtls_mpi_init( &P1 ); - mbedtls_mpi_init( &Q1 ); - mbedtls_mpi_init( &R ); - - if( f_rng != NULL ) - { -#if defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_init( &D_blind ); -#else - mbedtls_mpi_init( &DP_blind ); - mbedtls_mpi_init( &DQ_blind ); -#endif - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ ); -#endif - - mbedtls_mpi_init( &I ); - mbedtls_mpi_init( &C ); - - /* End of MPI initialization */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); - if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) - { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) ); - - if( f_rng != NULL ) - { - /* - * Blinding - * T = T * Vi mod N - */ - MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); - - /* - * Exponent blinding - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); - -#if defined(MBEDTLS_RSA_NO_CRT) - /* - * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) ); - - D = &D_blind; -#else - /* - * DP_blind = ( P - 1 ) * R + DP - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind, - &ctx->DP ) ); - - DP = &DP_blind; - - /* - * DQ_blind = ( Q - 1 ) * R + DQ - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind, - &ctx->DQ ) ); - - DQ = &DQ_blind; -#endif /* MBEDTLS_RSA_NO_CRT */ - } - -#if defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) ); -#else - /* - * Faster decryption using the CRT - * - * TP = input ^ dP mod P - * TQ = input ^ dQ mod Q - */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) ); - - /* - * T = (TP - TQ) * (Q^-1 mod P) mod P - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) ); - - /* - * T = TQ + T * Q - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) ); -#endif /* MBEDTLS_RSA_NO_CRT */ - - if( f_rng != NULL ) - { - /* - * Unblind - * T = T * Vf mod N - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); - } - - /* Verify the result to prevent glitching attacks. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E, - &ctx->N, &ctx->RN ) ); - if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto cleanup; - } - - olen = ctx->len; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - mbedtls_mpi_free( &P1 ); - mbedtls_mpi_free( &Q1 ); - mbedtls_mpi_free( &R ); - - if( f_rng != NULL ) - { -#if defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free( &D_blind ); -#else - mbedtls_mpi_free( &DP_blind ); - mbedtls_mpi_free( &DQ_blind ); -#endif - } - - mbedtls_mpi_free( &T ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ ); -#endif - - mbedtls_mpi_free( &C ); - mbedtls_mpi_free( &I ); - - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); - - return( 0 ); -} - -#if defined(MBEDTLS_PKCS1_V21) -/** - * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. - * - * \param dst buffer to mask - * \param dlen length of destination buffer - * \param src source of the mask generation - * \param slen length of the source buffer - * \param md_ctx message digest context to use - */ -static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, - size_t slen, mbedtls_md_context_t *md_ctx ) -{ - unsigned char mask[MBEDTLS_MD_MAX_SIZE]; - unsigned char counter[4]; - unsigned char *p; - unsigned int hlen; - size_t i, use_len; - int ret = 0; - - memset( mask, 0, MBEDTLS_MD_MAX_SIZE ); - memset( counter, 0, 4 ); - - hlen = mbedtls_md_get_size( md_ctx->md_info ); - - /* Generate and apply dbMask */ - p = dst; - - while( dlen > 0 ) - { - use_len = hlen; - if( dlen < hlen ) - use_len = dlen; - - if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 ) - goto exit; - - for( i = 0; i < use_len; ++i ) - *p++ ^= mask[i]; - - counter[3]++; - - dlen -= use_len; - } - -exit: - mbedtls_platform_zeroize( mask, sizeof( mask ) ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function - */ -int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - const unsigned char *label, size_t label_len, - size_t ilen, - const unsigned char *input, - unsigned char *output ) -{ - size_t olen; - int ret; - unsigned char *p = output; - unsigned int hlen; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( ilen == 0 || input != NULL ); - RSA_VALIDATE_RET( label_len == 0 || label != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( f_rng == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - olen = ctx->len; - hlen = mbedtls_md_get_size( md_info ); - - /* first comparison checks for overflow */ - if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - memset( output, 0, olen ); - - *p++ = 0; - - /* Generate a random octet string seed */ - if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); - - p += hlen; - - /* Construct DB */ - if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 ) - return( ret ); - p += hlen; - p += olen - 2 * hlen - 2 - ilen; - *p++ = 1; - if( ilen != 0 ) - memcpy( p, input, ilen ); - - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - goto exit; - - /* maskedDB: Apply dbMask to DB */ - if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, - &md_ctx ) ) != 0 ) - goto exit; - - /* maskedSeed: Apply seedMask to seed */ - if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, - &md_ctx ) ) != 0 ) - goto exit; - -exit: - mbedtls_md_free( &md_ctx ); - - if( ret != 0 ) - return( ret ); - - return( ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, output, output ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function - */ -int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t ilen, - const unsigned char *input, - unsigned char *output ) -{ - size_t nb_pad, olen; - int ret; - unsigned char *p = output; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - olen = ctx->len; - - /* first comparison checks for overflow */ - if( ilen + 11 < ilen || olen < ilen + 11 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - nb_pad = olen - 3 - ilen; - - *p++ = 0; - if( mode == MBEDTLS_RSA_PUBLIC ) - { - if( f_rng == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - *p++ = MBEDTLS_RSA_CRYPT; - - while( nb_pad-- > 0 ) - { - int rng_dl = 100; - - do { - ret = f_rng( p_rng, p, 1 ); - } while( *p == 0 && --rng_dl && ret == 0 ); - - /* Check if RNG failed to generate data */ - if( rng_dl == 0 || ret != 0 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); - - p++; - } - } - else - { - *p++ = MBEDTLS_RSA_SIGN; - - while( nb_pad-- > 0 ) - *p++ = 0xFF; - } - - *p++ = 0; - if( ilen != 0 ) - memcpy( p, input, ilen ); - - return( ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, output, output ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Add the message padding, then do an RSA operation - */ -int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t ilen, - const unsigned char *input, - unsigned char *output ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( ilen == 0 || input != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen, - input, output ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0, - ilen, input, output ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function - */ -int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - const unsigned char *label, size_t label_len, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ) -{ - int ret; - size_t ilen, i, pad_len; - unsigned char *p, bad, pad_done; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; - unsigned int hlen; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( label_len == 0 || label != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - - /* - * Parameters sanity checks - */ - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - ilen = ctx->len; - - if( ilen < 16 || ilen > sizeof( buf ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hlen = mbedtls_md_get_size( md_info ); - - // checking for integer underflow - if( 2 * hlen + 2 > ilen ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * RSA operation - */ - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, input, buf ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); - - if( ret != 0 ) - goto cleanup; - - /* - * Unmask data and generate lHash - */ - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - { - mbedtls_md_free( &md_ctx ); - goto cleanup; - } - - /* seed: Apply seedMask to maskedSeed */ - if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, - &md_ctx ) ) != 0 || - /* DB: Apply dbMask to maskedDB */ - ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, - &md_ctx ) ) != 0 ) - { - mbedtls_md_free( &md_ctx ); - goto cleanup; - } - - mbedtls_md_free( &md_ctx ); - - /* Generate lHash */ - if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 ) - goto cleanup; - - /* - * Check contents, in "constant-time" - */ - p = buf; - bad = 0; - - bad |= *p++; /* First byte must be 0 */ - - p += hlen; /* Skip seed */ - - /* Check lHash */ - for( i = 0; i < hlen; i++ ) - bad |= lhash[i] ^ *p++; - - /* Get zero-padding len, but always read till end of buffer - * (minus one, for the 01 byte) */ - pad_len = 0; - pad_done = 0; - for( i = 0; i < ilen - 2 * hlen - 2; i++ ) - { - pad_done |= p[i]; - pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; - } - - p += pad_len; - bad |= *p++ ^ 0x01; - - /* - * The only information "leaked" is whether the padding was correct or not - * (eg, no data is copied if it was not correct). This meets the - * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between - * the different error conditions. - */ - if( bad != 0 ) - { - ret = MBEDTLS_ERR_RSA_INVALID_PADDING; - goto cleanup; - } - - if( ilen - ( p - buf ) > output_max_len ) - { - ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; - goto cleanup; - } - - *olen = ilen - (p - buf); - if( *olen != 0 ) - memcpy( output, p, *olen ); - ret = 0; - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - mbedtls_platform_zeroize( lhash, sizeof( lhash ) ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches. - * - * \param value The value to analyze. - * \return Zero if \p value is zero, otherwise all-bits-one. - */ -static unsigned all_or_nothing_int( unsigned value ) -{ - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif -} - -/** Check whether a size is out of bounds, without branches. - * - * This is equivalent to `size > max`, but is likely to be compiled to - * to code using bitwise operation rather than a branch. - * - * \param size Size to check. - * \param max Maximum desired value for \p size. - * \return \c 0 if `size <= max`. - * \return \c 1 if `size > max`. - */ -static unsigned size_greater_than( size_t size, size_t max ) -{ - /* Return the sign bit (1 for negative) of (max - size). */ - return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) ); -} - -/** Choose between two integer values, without branches. - * - * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled - * to code using bitwise operation rather than a branch. - * - * \param cond Condition to test. - * \param if1 Value to use if \p cond is nonzero. - * \param if0 Value to use if \p cond is zero. - * \return \c if1 if \p cond is nonzero, otherwise \c if0. - */ -static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 ) -{ - unsigned mask = all_or_nothing_int( cond ); - return( ( mask & if1 ) | (~mask & if0 ) ); -} - -/** Shift some data towards the left inside a buffer without leaking - * the length of the data through side channels. - * - * `mem_move_to_left(start, total, offset)` is functionally equivalent to - * ``` - * memmove(start, start + offset, total - offset); - * memset(start + offset, 0, total - offset); - * ``` - * but it strives to use a memory access pattern (and thus total timing) - * that does not depend on \p offset. This timing independence comes at - * the expense of performance. - * - * \param start Pointer to the start of the buffer. - * \param total Total size of the buffer. - * \param offset Offset from which to copy \p total - \p offset bytes. - */ -static void mem_move_to_left( void *start, - size_t total, - size_t offset ) -{ - volatile unsigned char *buf = start; - size_t i, n; - if( total == 0 ) - return; - for( i = 0; i < total; i++ ) - { - unsigned no_op = size_greater_than( total - offset, i ); - /* The first `total - offset` passes are a no-op. The last - * `offset` passes shift the data one byte to the left and - * zero out the last byte. */ - for( n = 0; n < total - 1; n++ ) - { - unsigned char current = buf[n]; - unsigned char next = buf[n+1]; - buf[n] = if_int( no_op, current, next ); - } - buf[total-1] = if_int( no_op, buf[total-1], 0 ); - } -} - -/* - * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function - */ -int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ) -{ - int ret; - size_t ilen, i, plaintext_max_size; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - /* The following variables take sensitive values: their value must - * not leak into the observable behavior of the function other than - * the designated outputs (output, olen, return value). Otherwise - * this would open the execution of the function to - * side-channel-based variants of the Bleichenbacher padding oracle - * attack. Potential side channels include overall timing, memory - * access patterns (especially visible to an adversary who has access - * to a shared memory cache), and branches (especially visible to - * an adversary who has access to a shared code cache or to a shared - * branch predictor). */ - size_t pad_count = 0; - unsigned bad = 0; - unsigned char pad_done = 0; - size_t plaintext_size = 0; - unsigned output_too_large; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - - ilen = ctx->len; - plaintext_max_size = ( output_max_len > ilen - 11 ? - ilen - 11 : - output_max_len ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( ilen < 16 || ilen > sizeof( buf ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, input, buf ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); - - if( ret != 0 ) - goto cleanup; - - /* Check and get padding length in constant time and constant - * memory trace. The first byte must be 0. */ - bad |= buf[0]; - - if( mode == MBEDTLS_RSA_PRIVATE ) - { - /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00 - * where PS must be at least 8 nonzero bytes. */ - bad |= buf[1] ^ MBEDTLS_RSA_CRYPT; - - /* Read the whole buffer. Set pad_done to nonzero if we find - * the 0x00 byte and remember the padding length in pad_count. */ - for( i = 2; i < ilen; i++ ) - { - pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1; - pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; - } - } - else - { - /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00 - * where PS must be at least 8 bytes with the value 0xFF. */ - bad |= buf[1] ^ MBEDTLS_RSA_SIGN; - - /* Read the whole buffer. Set pad_done to nonzero if we find - * the 0x00 byte and remember the padding length in pad_count. - * If there's a non-0xff byte in the padding, the padding is bad. */ - for( i = 2; i < ilen; i++ ) - { - pad_done |= if_int( buf[i], 0, 1 ); - pad_count += if_int( pad_done, 0, 1 ); - bad |= if_int( pad_done, 0, buf[i] ^ 0xFF ); - } - } - - /* If pad_done is still zero, there's no data, only unfinished padding. */ - bad |= if_int( pad_done, 0, 1 ); - - /* There must be at least 8 bytes of padding. */ - bad |= size_greater_than( 8, pad_count ); - - /* If the padding is valid, set plaintext_size to the number of - * remaining bytes after stripping the padding. If the padding - * is invalid, avoid leaking this fact through the size of the - * output: use the maximum message size that fits in the output - * buffer. Do it without branches to avoid leaking the padding - * validity through timing. RSA keys are small enough that all the - * size_t values involved fit in unsigned int. */ - plaintext_size = if_int( bad, - (unsigned) plaintext_max_size, - (unsigned) ( ilen - pad_count - 3 ) ); - - /* Set output_too_large to 0 if the plaintext fits in the output - * buffer and to 1 otherwise. */ - output_too_large = size_greater_than( plaintext_size, - plaintext_max_size ); - - /* Set ret without branches to avoid timing attacks. Return: - * - INVALID_PADDING if the padding is bad (bad != 0). - * - OUTPUT_TOO_LARGE if the padding is good but the decrypted - * plaintext does not fit in the output buffer. - * - 0 if the padding is correct. */ - ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING, - if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE, - 0 ) ); - - /* If the padding is bad or the plaintext is too large, zero the - * data that we're about to copy to the output buffer. - * We need to copy the same amount of data - * from the same buffer whether the padding is good or not to - * avoid leaking the padding validity through overall timing or - * through memory or cache access patterns. */ - bad = all_or_nothing_int( bad | output_too_large ); - for( i = 11; i < ilen; i++ ) - buf[i] &= ~bad; - - /* If the plaintext is too large, truncate it to the buffer size. - * Copy anyway to avoid revealing the length through timing, because - * revealing the length is as bad as revealing the padding validity - * for a Bleichenbacher attack. */ - plaintext_size = if_int( output_too_large, - (unsigned) plaintext_max_size, - (unsigned) plaintext_size ); - - /* Move the plaintext to the leftmost position where it can start in - * the working buffer, i.e. make it start plaintext_max_size from - * the end of the buffer. Do this with a memory access trace that - * does not depend on the plaintext size. After this move, the - * starting location of the plaintext is no longer sensitive - * information. */ - mem_move_to_left( buf + ilen - plaintext_max_size, - plaintext_max_size, - plaintext_max_size - plaintext_size ); - - /* Finally copy the decrypted plaintext plus trailing zeros into the output - * buffer. If output_max_len is 0, then output may be an invalid pointer - * and the result of memcpy() would be undefined; prevent undefined - * behavior making sure to depend only on output_max_len (the size of the - * user-provided output buffer), which is independent from plaintext - * length, validity of padding, success of the decryption, and other - * secrets. */ - if( output_max_len != 0 ) - memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size ); - - /* Report the amount of data we copied to the output buffer. In case - * of errors (bad padding or output too large), the value of *olen - * when this function returns is not specified. Making it equivalent - * to the good case limits the risks of leaking the padding validity. */ - *olen = plaintext_size; - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation, then remove the message padding - */ -int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen, - input, output, output_max_len ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0, - olen, input, output, - output_max_len ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function - */ -int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - size_t olen; - unsigned char *p = sig; - unsigned char salt[MBEDTLS_MD_MAX_SIZE]; - size_t slen, min_slen, hlen, offset = 0; - int ret; - size_t msb; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( f_rng == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - olen = ctx->len; - - if( md_alg != MBEDTLS_MD_NONE ) - { - /* Gather length of hash to sign */ - md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - } - - md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hlen = mbedtls_md_get_size( md_info ); - - /* Calculate the largest possible salt length. Normally this is the hash - * length, which is the maximum length the salt can have. If there is not - * enough room, use the maximum salt length that fits. The constraint is - * that the hash length plus the salt length plus 2 bytes must be at most - * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 - * (PKCS#1 v2.2) §9.1.1 step 3. */ - min_slen = hlen - 2; - if( olen < hlen + min_slen + 2 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - else if( olen >= hlen + hlen + 2 ) - slen = hlen; - else - slen = olen - hlen - 2; - - memset( sig, 0, olen ); - - /* Generate salt of length slen */ - if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); - - /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ - msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - p += olen - hlen - slen - 2; - *p++ = 0x01; - memcpy( p, salt, slen ); - p += slen; - - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - goto exit; - - /* Generate H = Hash( M' ) */ - if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 ) - goto exit; - - /* Compensate for boundary condition when applying mask */ - if( msb % 8 == 0 ) - offset = 1; - - /* maskedDB: Apply dbMask to DB */ - if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, - &md_ctx ) ) != 0 ) - goto exit; - - msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - sig[0] &= 0xFF >> ( olen * 8 - msb ); - - p += hlen; - *p++ = 0xBC; - - mbedtls_platform_zeroize( salt, sizeof( salt ) ); - -exit: - mbedtls_md_free( &md_ctx ); - - if( ret != 0 ) - return( ret ); - - return( ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, sig, sig ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function - */ - -/* Construct a PKCS v1.5 encoding of a hashed message - * - * This is used both for signature generation and verification. - * - * Parameters: - * - md_alg: Identifies the hash algorithm used to generate the given hash; - * MBEDTLS_MD_NONE if raw data is signed. - * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE. - * - hash: Buffer containing the hashed message or the raw data. - * - dst_len: Length of the encoded message. - * - dst: Buffer to hold the encoded message. - * - * Assumptions: - * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE. - * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE. - * - dst points to a buffer of size at least dst_len. - * - */ -static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - size_t dst_len, - unsigned char *dst ) -{ - size_t oid_size = 0; - size_t nb_pad = dst_len; - unsigned char *p = dst; - const char *oid = NULL; - - /* Are we signing hashed or raw data? */ - if( md_alg != MBEDTLS_MD_NONE ) - { - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - - /* Double-check that 8 + hashlen + oid_size can be used as a - * 1-byte ASN.1 length encoding and that there's no overflow. */ - if( 8 + hashlen + oid_size >= 0x80 || - 10 + hashlen < hashlen || - 10 + hashlen + oid_size < 10 + hashlen ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Static bounds check: - * - Need 10 bytes for five tag-length pairs. - * (Insist on 1-byte length encodings to protect against variants of - * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) - * - Need hashlen bytes for hash - * - Need oid_size bytes for hash alg OID. - */ - if( nb_pad < 10 + hashlen + oid_size ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - nb_pad -= 10 + hashlen + oid_size; - } - else - { - if( nb_pad < hashlen ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - nb_pad -= hashlen; - } - - /* Need space for signature header and padding delimiter (3 bytes), - * and 8 bytes for the minimal padding */ - if( nb_pad < 3 + 8 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - nb_pad -= 3; - - /* Now nb_pad is the amount of memory to be filled - * with padding, and at least 8 bytes long. */ - - /* Write signature header and padding */ - *p++ = 0; - *p++ = MBEDTLS_RSA_SIGN; - memset( p, 0xFF, nb_pad ); - p += nb_pad; - *p++ = 0; - - /* Are we signing raw data? */ - if( md_alg == MBEDTLS_MD_NONE ) - { - memcpy( p, hash, hashlen ); - return( 0 ); - } - - /* Signing hashed data, add corresponding ASN.1 structure - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest } - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * Digest ::= OCTET STRING - * - * Schematic: - * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] - * TAG-NULL + LEN [ NULL ] ] - * TAG-OCTET + LEN [ HASH ] ] - */ - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char)( 0x08 + oid_size + hashlen ); - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char)( 0x04 + oid_size ); - *p++ = MBEDTLS_ASN1_OID; - *p++ = (unsigned char) oid_size; - memcpy( p, oid, oid_size ); - p += oid_size; - *p++ = MBEDTLS_ASN1_NULL; - *p++ = 0x00; - *p++ = MBEDTLS_ASN1_OCTET_STRING; - *p++ = (unsigned char) hashlen; - memcpy( p, hash, hashlen ); - p += hashlen; - - /* Just a sanity-check, should be automatic - * after the initial bounds check. */ - if( p != dst + dst_len ) - { - mbedtls_platform_zeroize( dst, dst_len ); - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - return( 0 ); -} - -/* - * Do an RSA operation to sign the message digest - */ -int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - int ret; - unsigned char *sig_try = NULL, *verif = NULL; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Prepare PKCS1-v1.5 encoding (padding and hash identifier) - */ - - if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, - ctx->len, sig ) ) != 0 ) - return( ret ); - - /* - * Call respective RSA primitive - */ - - if( mode == MBEDTLS_RSA_PUBLIC ) - { - /* Skip verification on a public key operation */ - return( mbedtls_rsa_public( ctx, sig, sig ) ); - } - - /* Private key operation - * - * In order to prevent Lenstra's attack, make the signature in a - * temporary buffer and check it before returning it. - */ - - sig_try = mbedtls_calloc( 1, ctx->len ); - if( sig_try == NULL ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - verif = mbedtls_calloc( 1, ctx->len ); - if( verif == NULL ) - { - mbedtls_free( sig_try ); - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - } - - MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) ); - - if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED; - goto cleanup; - } - - memcpy( sig, sig_try, ctx->len ); - -cleanup: - mbedtls_free( sig_try ); - mbedtls_free( verif ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation to sign the message digest - */ -int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function - */ -int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - mbedtls_md_type_t mgf1_hash_id, - int expected_salt_len, - const unsigned char *sig ) -{ - int ret; - size_t siglen; - unsigned char *p; - unsigned char *hash_start; - unsigned char result[MBEDTLS_MD_MAX_SIZE]; - unsigned char zeros[8]; - unsigned int hlen; - size_t observed_salt_len, msb; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - siglen = ctx->len; - - if( siglen < 16 || siglen > sizeof( buf ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, sig, buf ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf ); - - if( ret != 0 ) - return( ret ); - - p = buf; - - if( buf[siglen - 1] != 0xBC ) - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - - if( md_alg != MBEDTLS_MD_NONE ) - { - /* Gather length of hash to sign */ - md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - } - - md_info = mbedtls_md_info_from_type( mgf1_hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hlen = mbedtls_md_get_size( md_info ); - - memset( zeros, 0, 8 ); - - /* - * Note: EMSA-PSS verification is over the length of N - 1 bits - */ - msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - - if( buf[0] >> ( 8 - siglen * 8 + msb ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* Compensate for boundary condition when applying mask */ - if( msb % 8 == 0 ) - { - p++; - siglen -= 1; - } - - if( siglen < hlen + 2 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - hash_start = p + siglen - hlen - 1; - - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - goto exit; - - ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx ); - if( ret != 0 ) - goto exit; - - buf[0] &= 0xFF >> ( siglen * 8 - msb ); - - while( p < hash_start - 1 && *p == 0 ) - p++; - - if( *p++ != 0x01 ) - { - ret = MBEDTLS_ERR_RSA_INVALID_PADDING; - goto exit; - } - - observed_salt_len = hash_start - p; - - if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY && - observed_salt_len != (size_t) expected_salt_len ) - { - ret = MBEDTLS_ERR_RSA_INVALID_PADDING; - goto exit; - } - - /* - * Generate H = Hash( M' ) - */ - ret = mbedtls_md_starts( &md_ctx ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_update( &md_ctx, zeros, 8 ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_update( &md_ctx, hash, hashlen ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_update( &md_ctx, p, observed_salt_len ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_finish( &md_ctx, result ); - if ( ret != 0 ) - goto exit; - - if( memcmp( hash_start, result, hlen ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto exit; - } - -exit: - mbedtls_md_free( &md_ctx ); - - return( ret ); -} - -/* - * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function - */ -int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ) -{ - mbedtls_md_type_t mgf1_hash_id; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE ) - ? (mbedtls_md_type_t) ctx->hash_id - : md_alg; - - return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode, - md_alg, hashlen, hash, - mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY, - sig ) ); - -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function - */ -int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ) -{ - int ret = 0; - size_t sig_len; - unsigned char *encoded = NULL, *encoded_expected = NULL; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - sig_len = ctx->len; - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Prepare expected PKCS1 v1.5 encoding of hash. - */ - - if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL || - ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL ) - { - ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; - goto cleanup; - } - - if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len, - encoded_expected ) ) != 0 ) - goto cleanup; - - /* - * Apply RSA primitive to get what should be PKCS1 encoded hash. - */ - - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, sig, encoded ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded ); - if( ret != 0 ) - goto cleanup; - - /* - * Compare - */ - - if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected, - sig_len ) ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - - if( encoded != NULL ) - { - mbedtls_platform_zeroize( encoded, sig_len ); - mbedtls_free( encoded ); - } - - if( encoded_expected != NULL ) - { - mbedtls_platform_zeroize( encoded_expected, sig_len ); - mbedtls_free( encoded_expected ); - } - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation and check the message digest - */ -int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -/* - * Copy the components of an RSA key - */ -int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) -{ - int ret; - RSA_VALIDATE_RET( dst != NULL ); - RSA_VALIDATE_RET( src != NULL ); - - dst->ver = src->ver; - dst->len = src->len; - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) ); -#endif - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) ); - - dst->padding = src->padding; - dst->hash_id = src->hash_id; - -cleanup: - if( ret != 0 ) - mbedtls_rsa_free( dst ); - - return( ret ); -} - -/* - * Free the components of an RSA key - */ -void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->Vi ); - mbedtls_mpi_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->RN ); - mbedtls_mpi_free( &ctx->D ); - mbedtls_mpi_free( &ctx->Q ); - mbedtls_mpi_free( &ctx->P ); - mbedtls_mpi_free( &ctx->E ); - mbedtls_mpi_free( &ctx->N ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free( &ctx->RQ ); - mbedtls_mpi_free( &ctx->RP ); - mbedtls_mpi_free( &ctx->QP ); - mbedtls_mpi_free( &ctx->DQ ); - mbedtls_mpi_free( &ctx->DP ); -#endif /* MBEDTLS_RSA_NO_CRT */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif -} - -#endif /* !MBEDTLS_RSA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#include "mbedtls/sha1.h" - -/* - * Example RSA-1024 keypair, for test purposes - */ -#define KEY_LEN 128 - -#define RSA_N "9292758453063D803DD603D5E777D788" \ - "8ED1D5BF35786190FA2F23EBC0848AEA" \ - "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ - "7130B9CED7ACDF54CFC7555AC14EEBAB" \ - "93A89813FBF3C4F8066D2D800F7C38A8" \ - "1AE31942917403FF4946B0A83D3D3E05" \ - "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ - "5E94BB77B07507233A0BC7BAC8F90F79" - -#define RSA_E "10001" - -#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ - "66CA472BC44D253102F8B4A9D3BFA750" \ - "91386C0077937FE33FA3252D28855837" \ - "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ - "DF79C5CE07EE72C7F123142198164234" \ - "CABB724CF78B8173B9F880FC86322407" \ - "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ - "071513A1E85B5DFA031F21ECAE91A34D" - -#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ - "2C01CAD19EA484A87EA4377637E75500" \ - "FCB2005C5C7DD6EC4AC023CDA285D796" \ - "C3D9E75E1EFC42488BB4F1D13AC30A57" - -#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ - "E211C2B9E5DB1ED0BF61D0D9899620F4" \ - "910E4168387E3C30AA1E00C339A79508" \ - "8452DD96A9A5EA5D9DCA68DA636032AF" - -#define PT_LEN 24 -#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ - "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" - -#if defined(MBEDTLS_PKCS1_V15) -static int myrand( void *rng_state, unsigned char *output, size_t len ) -{ -#if !defined(__OpenBSD__) - size_t i; - - if( rng_state != NULL ) - rng_state = NULL; - - for( i = 0; i < len; ++i ) - output[i] = rand(); -#else - if( rng_state != NULL ) - rng_state = NULL; - - arc4random_buf( output, len ); -#endif /* !OpenBSD */ - - return( 0 ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Checkup routine - */ -int mbedtls_rsa_self_test( int verbose ) -{ - int ret = 0; -#if defined(MBEDTLS_PKCS1_V15) - size_t len; - mbedtls_rsa_context rsa; - unsigned char rsa_plaintext[PT_LEN]; - unsigned char rsa_decrypted[PT_LEN]; - unsigned char rsa_ciphertext[KEY_LEN]; -#if defined(MBEDTLS_SHA1_C) - unsigned char sha1sum[20]; -#endif - - mbedtls_mpi K; - - mbedtls_mpi_init( &K ); - mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) ); - - MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) ); - - if( verbose != 0 ) - mbedtls_printf( " RSA key validation: " ); - - if( mbedtls_rsa_check_pubkey( &rsa ) != 0 || - mbedtls_rsa_check_privkey( &rsa ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n PKCS#1 encryption : " ); - - memcpy( rsa_plaintext, RSA_PT, PT_LEN ); - - if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, - PT_LEN, rsa_plaintext, - rsa_ciphertext ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n PKCS#1 decryption : " ); - - if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, - &len, rsa_ciphertext, rsa_decrypted, - sizeof(rsa_decrypted) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -#if defined(MBEDTLS_SHA1_C) - if( verbose != 0 ) - mbedtls_printf( " PKCS#1 data sign : " ); - - if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, - MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0, - sha1sum, rsa_ciphertext ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n PKCS#1 sig. verify: " ); - - if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, - MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, - sha1sum, rsa_ciphertext ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); -#endif /* MBEDTLS_SHA1_C */ - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -cleanup: - mbedtls_mpi_free( &K ); - mbedtls_rsa_free( &rsa ); -#else /* MBEDTLS_PKCS1_V15 */ - ((void) verbose); -#endif /* MBEDTLS_PKCS1_V15 */ - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_RSA_C */ diff --git a/library/rsa_internal.c b/library/rsa_internal.c deleted file mode 100644 index 9a42d47ceb..0000000000 --- a/library/rsa_internal.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Helper functions for the RSA module - * - * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_RSA_C) - -#include "mbedtls/rsa.h" -#include "mbedtls/bignum.h" -#include "mbedtls/rsa_internal.h" - -/* - * Compute RSA prime factors from public and private exponents - * - * Summary of algorithm: - * Setting F := lcm(P-1,Q-1), the idea is as follows: - * - * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2) - * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the - * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four - * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1) - * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime - * factors of N. - * - * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same - * construction still applies since (-)^K is the identity on the set of - * roots of 1 in Z/NZ. - * - * The public and private key primitives (-)^E and (-)^D are mutually inverse - * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e. - * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L. - * Splitting L = 2^t * K with K odd, we have - * - * DE - 1 = FL = (F/2) * (2^(t+1)) * K, - * - * so (F / 2) * K is among the numbers - * - * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord - * - * where ord is the order of 2 in (DE - 1). - * We can therefore iterate through these numbers apply the construction - * of (a) and (b) above to attempt to factor N. - * - */ -int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, - mbedtls_mpi const *E, mbedtls_mpi const *D, - mbedtls_mpi *P, mbedtls_mpi *Q ) -{ - int ret = 0; - - uint16_t attempt; /* Number of current attempt */ - uint16_t iter; /* Number of squares computed in the current attempt */ - - uint16_t order; /* Order of 2 in DE - 1 */ - - mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */ - mbedtls_mpi K; /* Temporary holding the current candidate */ - - const unsigned char primes[] = { 2, - 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, - 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, - 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251 - }; - - const size_t num_primes = sizeof( primes ) / sizeof( *primes ); - - if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || - mbedtls_mpi_cmp_int( D, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( D, N ) >= 0 || - mbedtls_mpi_cmp_int( E, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) - { - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - } - - /* - * Initializations and temporary changes - */ - - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &T ); - - /* T := DE - 1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, D, E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &T, &T, 1 ) ); - - if( ( order = (uint16_t) mbedtls_mpi_lsb( &T ) ) == 0 ) - { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - /* After this operation, T holds the largest odd divisor of DE - 1. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &T, order ) ); - - /* - * Actual work - */ - - /* Skip trying 2 if N == 1 mod 8 */ - attempt = 0; - if( N->p[0] % 8 == 1 ) - attempt = 1; - - for( ; attempt < num_primes; ++attempt ) - { - mbedtls_mpi_lset( &K, primes[attempt] ); - - /* Check if gcd(K,N) = 1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); - if( mbedtls_mpi_cmp_int( P, 1 ) != 0 ) - continue; - - /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ... - * and check whether they have nontrivial GCD with N. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, &T, N, - Q /* temporarily use Q for storing Montgomery - * multiplication helper values */ ) ); - - for( iter = 1; iter <= order; ++iter ) - { - /* If we reach 1 prematurely, there's no point - * in continuing to square K */ - if( mbedtls_mpi_cmp_int( &K, 1 ) == 0 ) - break; - - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); - - if( mbedtls_mpi_cmp_int( P, 1 ) == 1 && - mbedtls_mpi_cmp_mpi( P, N ) == -1 ) - { - /* - * Have found a nontrivial divisor P of N. - * Set Q := N / P. - */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, NULL, N, P ) ); - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) ); - } - - /* - * If we get here, then either we prematurely aborted the loop because - * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must - * be 1 if D,E,N were consistent. - * Check if that's the case and abort if not, to avoid very long, - * yet eventually failing, computations if N,D,E were not sane. - */ - if( mbedtls_mpi_cmp_int( &K, 1 ) != 0 ) - { - break; - } - } - - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - -cleanup: - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &T ); - return( ret ); -} - -/* - * Given P, Q and the public exponent E, deduce D. - * This is essentially a modular inversion. - */ -int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P, - mbedtls_mpi const *Q, - mbedtls_mpi const *E, - mbedtls_mpi *D ) -{ - int ret = 0; - mbedtls_mpi K, L; - - if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || - mbedtls_mpi_cmp_int( Q, 1 ) <= 0 || - mbedtls_mpi_cmp_int( E, 0 ) == 0 ) - { - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - } - - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &L ); - - /* Temporarily put K := P-1 and L := Q-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); - - /* Temporarily put D := gcd(P-1, Q-1) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, &K, &L ) ); - - /* K := LCM(P-1, Q-1) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &L ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) ); - - /* Compute modular inverse of E in LCM(P-1, Q-1) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) ); - -cleanup: - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &L ); - - return( ret ); -} - -/* - * Check that RSA CRT parameters are in accordance with core parameters. - */ -int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *DP, - const mbedtls_mpi *DQ, const mbedtls_mpi *QP ) -{ - int ret = 0; - - mbedtls_mpi K, L; - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &L ); - - /* Check that DP - D == 0 mod P - 1 */ - if( DP != NULL ) - { - if( P == NULL ) - { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); - - if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* Check that DQ - D == 0 mod Q - 1 */ - if( DQ != NULL ) - { - if( Q == NULL ) - { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); - - if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* Check that QP * Q - 1 == 0 mod P */ - if( QP != NULL ) - { - if( P == NULL || Q == NULL ) - { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) ); - if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - -cleanup: - - /* Wrap MPI error codes by RSA check failure error code */ - if( ret != 0 && - ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED && - ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) - { - ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &L ); - - return( ret ); -} - -/* - * Check that core RSA parameters are sane. - */ -int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, - const mbedtls_mpi *Q, const mbedtls_mpi *D, - const mbedtls_mpi *E, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret = 0; - mbedtls_mpi K, L; - - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &L ); - - /* - * Step 1: If PRNG provided, check that P and Q are prime - */ - -#if defined(MBEDTLS_GENPRIME) - /* - * When generating keys, the strongest security we support aims for an error - * rate of at most 2^-100 and we are aiming for the same certainty here as - * well. - */ - if( f_rng != NULL && P != NULL && - ( ret = mbedtls_mpi_is_prime_ext( P, 50, f_rng, p_rng ) ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - if( f_rng != NULL && Q != NULL && - ( ret = mbedtls_mpi_is_prime_ext( Q, 50, f_rng, p_rng ) ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } -#else - ((void) f_rng); - ((void) p_rng); -#endif /* MBEDTLS_GENPRIME */ - - /* - * Step 2: Check that 1 < N = P * Q - */ - - if( P != NULL && Q != NULL && N != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) ); - if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( &K, N ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* - * Step 3: Check and 1 < D, E < N if present. - */ - - if( N != NULL && D != NULL && E != NULL ) - { - if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 || - mbedtls_mpi_cmp_int( E, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( D, N ) >= 0 || - mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* - * Step 4: Check that D, E are inverse modulo P-1 and Q-1 - */ - - if( P != NULL && Q != NULL && D != NULL && E != NULL ) - { - if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || - mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - /* Compute DE-1 mod P-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); - if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - /* Compute DE-1 mod Q-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); - if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - -cleanup: - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &L ); - - /* Wrap MPI error codes by RSA check failure error code */ - if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ) - { - ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - return( ret ); -} - -int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, mbedtls_mpi *DP, - mbedtls_mpi *DQ, mbedtls_mpi *QP ) -{ - int ret = 0; - mbedtls_mpi K; - mbedtls_mpi_init( &K ); - - /* DP = D mod P-1 */ - if( DP != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) ); - } - - /* DQ = D mod Q-1 */ - if( DQ != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) ); - } - - /* QP = Q^{-1} mod P */ - if( QP != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) ); - } - -cleanup: - mbedtls_mpi_free( &K ); - - return( ret ); -} - -#endif /* MBEDTLS_RSA_C */ diff --git a/library/sha1.c b/library/sha1.c deleted file mode 100644 index 355c83d2f7..0000000000 --- a/library/sha1.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SHA1_C) - -#include "mbedtls/sha1.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#define SHA1_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA ) - -#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if !defined(MBEDTLS_SHA1_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) -{ - SHA1_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); -} - -void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); -} - -void mbedtls_sha1_clone( mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src ) -{ - SHA1_VALIDATE( dst != NULL ); - SHA1_VALIDATE( src != NULL ); - - *dst = *src; -} - -/* - * SHA-1 context setup - */ -int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) -{ - SHA1_VALIDATE_RET( ctx != NULL ); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) -{ - mbedtls_sha1_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_SHA1_PROCESS_ALT) -int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, - const unsigned char data[64] ) -{ - uint32_t temp, W[16], A, B, C, D, E; - - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( (const unsigned char *)data != NULL ); - - GET_UINT32_BE( W[ 0], data, 0 ); - GET_UINT32_BE( W[ 1], data, 4 ); - GET_UINT32_BE( W[ 2], data, 8 ); - GET_UINT32_BE( W[ 3], data, 12 ); - GET_UINT32_BE( W[ 4], data, 16 ); - GET_UINT32_BE( W[ 5], data, 20 ); - GET_UINT32_BE( W[ 6], data, 24 ); - GET_UINT32_BE( W[ 7], data, 28 ); - GET_UINT32_BE( W[ 8], data, 32 ); - GET_UINT32_BE( W[ 9], data, 36 ); - GET_UINT32_BE( W[10], data, 40 ); - GET_UINT32_BE( W[11], data, 44 ); - GET_UINT32_BE( W[12], data, 48 ); - GET_UINT32_BE( W[13], data, 52 ); - GET_UINT32_BE( W[14], data, 56 ); - GET_UINT32_BE( W[15], data, 60 ); - -#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - -#define R(t) \ - ( \ - temp = W[( (t) - 3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \ - W[( (t) - 14 ) & 0x0F] ^ W[ (t) & 0x0F], \ - ( W[(t) & 0x0F] = S(temp,1) ) \ - ) - -#define P(a,b,c,d,e,x) \ - do \ - { \ - (e) += S((a),5) + F((b),(c),(d)) + K + (x); \ - (b) = S((b),30); \ - } while( 0 ) - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_sha1_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_SHA1_PROCESS_ALT */ - -/* - * SHA-1 process buffer - */ -int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - memcpy( (void *) (ctx->buffer + left), input, ilen ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_update( mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha1_update_ret( ctx, input, ilen ); -} -#endif - -/* - * SHA-1 final digest - */ -int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, - unsigned char output[20] ) -{ - int ret; - uint32_t used; - uint32_t high, low; - - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if( used <= 56 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 56 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 64 - used ); - - if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 56 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_BE( high, ctx->buffer, 56 ); - PUT_UINT32_BE( low, ctx->buffer, 60 ); - - if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT32_BE( ctx->state[0], output, 0 ); - PUT_UINT32_BE( ctx->state[1], output, 4 ); - PUT_UINT32_BE( ctx->state[2], output, 8 ); - PUT_UINT32_BE( ctx->state[3], output, 12 ); - PUT_UINT32_BE( ctx->state[4], output, 16 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, - unsigned char output[20] ) -{ - mbedtls_sha1_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_SHA1_ALT */ - -/* - * output = SHA-1( input buffer ) - */ -int mbedtls_sha1_ret( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - int ret; - mbedtls_sha1_context ctx; - - SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); - - mbedtls_sha1_init( &ctx ); - - if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_sha1_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - mbedtls_sha1_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * FIPS-180-1 test vectors - */ -static const unsigned char sha1_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const size_t sha1_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha1_test_sum[3][20] = -{ - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, - { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, - 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } -}; - -/* - * Checkup routine - */ -int mbedtls_sha1_self_test( int verbose ) -{ - int i, j, buflen, ret = 0; - unsigned char buf[1024]; - unsigned char sha1sum[20]; - mbedtls_sha1_context ctx; - - mbedtls_sha1_init( &ctx ); - - /* - * SHA-1 - */ - for( i = 0; i < 3; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); - - if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) - goto fail; - - if( i == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - { - ret = mbedtls_sha1_update_ret( &ctx, buf, buflen ); - if( ret != 0 ) - goto fail; - } - } - else - { - ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i], - sha1_test_buflen[i] ); - if( ret != 0 ) - goto fail; - } - - if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 ) - goto fail; - - if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - goto exit; - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - -exit: - mbedtls_sha1_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA1_C */ diff --git a/library/sha256.c b/library/sha256.c deleted file mode 100644 index 2dc0e1a2c9..0000000000 --- a/library/sha256.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * FIPS-180-2 compliant SHA-256 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The SHA-256 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SHA256_C) - -#include "mbedtls/sha256.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#define SHA256_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA ) -#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if !defined(MBEDTLS_SHA256_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -do { \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} while( 0 ) -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -do { \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} while( 0 ) -#endif - -void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) -{ - SHA256_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); -} - -void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); -} - -void mbedtls_sha256_clone( mbedtls_sha256_context *dst, - const mbedtls_sha256_context *src ) -{ - SHA256_VALIDATE( dst != NULL ); - SHA256_VALIDATE( src != NULL ); - - *dst = *src; -} - -/* - * SHA-256 context setup - */ -int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ) -{ - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - if( is224 == 0 ) - { - /* SHA-256 */ - ctx->state[0] = 0x6A09E667; - ctx->state[1] = 0xBB67AE85; - ctx->state[2] = 0x3C6EF372; - ctx->state[3] = 0xA54FF53A; - ctx->state[4] = 0x510E527F; - ctx->state[5] = 0x9B05688C; - ctx->state[6] = 0x1F83D9AB; - ctx->state[7] = 0x5BE0CD19; - } - else - { - /* SHA-224 */ - ctx->state[0] = 0xC1059ED8; - ctx->state[1] = 0x367CD507; - ctx->state[2] = 0x3070DD17; - ctx->state[3] = 0xF70E5939; - ctx->state[4] = 0xFFC00B31; - ctx->state[5] = 0x68581511; - ctx->state[6] = 0x64F98FA7; - ctx->state[7] = 0xBEFA4FA4; - } - - ctx->is224 = is224; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, - int is224 ) -{ - mbedtls_sha256_starts_ret( ctx, is224 ); -} -#endif - -#if !defined(MBEDTLS_SHA256_PROCESS_ALT) -static const uint32_t K[] = -{ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, -}; - -#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n)) -#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n)))) - -#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) -#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) - -#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) -#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) - -#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - -#define R(t) \ - ( \ - W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \ - S0(W[(t) - 15]) + W[(t) - 16] \ - ) - -#define P(a,b,c,d,e,f,g,h,x,K) \ - do \ - { \ - temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ - temp2 = S2(a) + F0((a),(b),(c)); \ - (d) += temp1; (h) = temp1 + temp2; \ - } while( 0 ) - -int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, - const unsigned char data[64] ) -{ - uint32_t temp1, temp2, W[64]; - uint32_t A[8]; - unsigned int i; - - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( (const unsigned char *)data != NULL ); - - for( i = 0; i < 8; i++ ) - A[i] = ctx->state[i]; - -#if defined(MBEDTLS_SHA256_SMALLER) - for( i = 0; i < 64; i++ ) - { - if( i < 16 ) - GET_UINT32_BE( W[i], data, 4 * i ); - else - R( i ); - - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); - - temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; - A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; - } -#else /* MBEDTLS_SHA256_SMALLER */ - for( i = 0; i < 16; i++ ) - GET_UINT32_BE( W[i], data, 4 * i ); - - for( i = 0; i < 16; i += 8 ) - { - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] ); - P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] ); - P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] ); - P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] ); - P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] ); - P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] ); - P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] ); - P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] ); - } - - for( i = 16; i < 64; i += 8 ) - { - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] ); - P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] ); - P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] ); - P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] ); - P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] ); - P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] ); - P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); - P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); - } -#endif /* MBEDTLS_SHA256_SMALLER */ - - for( i = 0; i < 8; i++ ) - ctx->state[i] += A[i]; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_process( mbedtls_sha256_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_sha256_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_SHA256_PROCESS_ALT */ - -/* - * SHA-256 process buffer - */ -int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - memcpy( (void *) (ctx->buffer + left), input, ilen ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_update( mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha256_update_ret( ctx, input, ilen ); -} -#endif - -/* - * SHA-256 final digest - */ -int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, - unsigned char output[32] ) -{ - int ret; - uint32_t used; - uint32_t high, low; - - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if( used <= 56 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 56 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 64 - used ); - - if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 56 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_BE( high, ctx->buffer, 56 ); - PUT_UINT32_BE( low, ctx->buffer, 60 ); - - if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT32_BE( ctx->state[0], output, 0 ); - PUT_UINT32_BE( ctx->state[1], output, 4 ); - PUT_UINT32_BE( ctx->state[2], output, 8 ); - PUT_UINT32_BE( ctx->state[3], output, 12 ); - PUT_UINT32_BE( ctx->state[4], output, 16 ); - PUT_UINT32_BE( ctx->state[5], output, 20 ); - PUT_UINT32_BE( ctx->state[6], output, 24 ); - - if( ctx->is224 == 0 ) - PUT_UINT32_BE( ctx->state[7], output, 28 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, - unsigned char output[32] ) -{ - mbedtls_sha256_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_SHA256_ALT */ - -/* - * output = SHA-256( input buffer ) - */ -int mbedtls_sha256_ret( const unsigned char *input, - size_t ilen, - unsigned char output[32], - int is224 ) -{ - int ret; - mbedtls_sha256_context ctx; - - SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); - SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); - - mbedtls_sha256_init( &ctx ); - - if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_sha256_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256( const unsigned char *input, - size_t ilen, - unsigned char output[32], - int is224 ) -{ - mbedtls_sha256_ret( input, ilen, output, is224 ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * FIPS-180-2 test vectors - */ -static const unsigned char sha256_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const size_t sha256_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha256_test_sum[6][32] = -{ - /* - * SHA-224 test vectors - */ - { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, - 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, - 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, - 0xE3, 0x6C, 0x9D, 0xA7 }, - { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, - 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, - 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, - 0x52, 0x52, 0x25, 0x25 }, - { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, - 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, - 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, - 0x4E, 0xE7, 0xAD, 0x67 }, - - /* - * SHA-256 test vectors - */ - { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, - 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, - 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, - 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, - { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, - 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, - 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, - 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, - { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, - 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, - 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, - 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } -}; - -/* - * Checkup routine - */ -int mbedtls_sha256_self_test( int verbose ) -{ - int i, j, k, buflen, ret = 0; - unsigned char *buf; - unsigned char sha256sum[32]; - mbedtls_sha256_context ctx; - - buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); - if( NULL == buf ) - { - if( verbose != 0 ) - mbedtls_printf( "Buffer allocation failed\n" ); - - return( 1 ); - } - - mbedtls_sha256_init( &ctx ); - - for( i = 0; i < 6; i++ ) - { - j = i % 3; - k = i < 3; - - if( verbose != 0 ) - mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); - - if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 ) - goto fail; - - if( j == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - { - ret = mbedtls_sha256_update_ret( &ctx, buf, buflen ); - if( ret != 0 ) - goto fail; - } - - } - else - { - ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j], - sha256_test_buflen[j] ); - if( ret != 0 ) - goto fail; - } - - if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 ) - goto fail; - - - if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - goto exit; - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - -exit: - mbedtls_sha256_free( &ctx ); - mbedtls_free( buf ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA256_C */ diff --git a/library/sha512.c b/library/sha512.c deleted file mode 100644 index bdd20b284a..0000000000 --- a/library/sha512.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * FIPS-180-2 compliant SHA-384/512 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The SHA-512 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SHA512_C) - -#include "mbedtls/sha512.h" -#include "mbedtls/platform_util.h" - -#if defined(_MSC_VER) || defined(__WATCOMC__) - #define UL64(x) x##ui64 -#else - #define UL64(x) x##ULL -#endif - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#define SHA512_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA ) -#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if !defined(MBEDTLS_SHA512_ALT) - -/* - * 64-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT64_BE -#define GET_UINT64_BE(n,b,i) \ -{ \ - (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ - | ( (uint64_t) (b)[(i) + 1] << 48 ) \ - | ( (uint64_t) (b)[(i) + 2] << 40 ) \ - | ( (uint64_t) (b)[(i) + 3] << 32 ) \ - | ( (uint64_t) (b)[(i) + 4] << 24 ) \ - | ( (uint64_t) (b)[(i) + 5] << 16 ) \ - | ( (uint64_t) (b)[(i) + 6] << 8 ) \ - | ( (uint64_t) (b)[(i) + 7] ); \ -} -#endif /* GET_UINT64_BE */ - -#ifndef PUT_UINT64_BE -#define PUT_UINT64_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ - (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 7] = (unsigned char) ( (n) ); \ -} -#endif /* PUT_UINT64_BE */ - -void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) -{ - SHA512_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); -} - -void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); -} - -void mbedtls_sha512_clone( mbedtls_sha512_context *dst, - const mbedtls_sha512_context *src ) -{ - SHA512_VALIDATE( dst != NULL ); - SHA512_VALIDATE( src != NULL ); - - *dst = *src; -} - -/* - * SHA-512 context setup - */ -int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ) -{ - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - if( is384 == 0 ) - { - /* SHA-512 */ - ctx->state[0] = UL64(0x6A09E667F3BCC908); - ctx->state[1] = UL64(0xBB67AE8584CAA73B); - ctx->state[2] = UL64(0x3C6EF372FE94F82B); - ctx->state[3] = UL64(0xA54FF53A5F1D36F1); - ctx->state[4] = UL64(0x510E527FADE682D1); - ctx->state[5] = UL64(0x9B05688C2B3E6C1F); - ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); - ctx->state[7] = UL64(0x5BE0CD19137E2179); - } - else - { - /* SHA-384 */ - ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); - ctx->state[1] = UL64(0x629A292A367CD507); - ctx->state[2] = UL64(0x9159015A3070DD17); - ctx->state[3] = UL64(0x152FECD8F70E5939); - ctx->state[4] = UL64(0x67332667FFC00B31); - ctx->state[5] = UL64(0x8EB44A8768581511); - ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); - ctx->state[7] = UL64(0x47B5481DBEFA4FA4); - } - - ctx->is384 = is384; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, - int is384 ) -{ - mbedtls_sha512_starts_ret( ctx, is384 ); -} -#endif - -#if !defined(MBEDTLS_SHA512_PROCESS_ALT) - -/* - * Round constants - */ -static const uint64_t K[80] = -{ - UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), - UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), - UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), - UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), - UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), - UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), - UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), - UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), - UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), - UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), - UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), - UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), - UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), - UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), - UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), - UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), - UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), - UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), - UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), - UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), - UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), - UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), - UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), - UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), - UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), - UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), - UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), - UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), - UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), - UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), - UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), - UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), - UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), - UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), - UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), - UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), - UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), - UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), - UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), - UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) -}; - -int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, - const unsigned char data[128] ) -{ - int i; - uint64_t temp1, temp2, W[80]; - uint64_t A, B, C, D, E, F, G, H; - - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( (const unsigned char *)data != NULL ); - -#define SHR(x,n) ((x) >> (n)) -#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n)))) - -#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) -#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) - -#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) -#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) - -#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - -#define P(a,b,c,d,e,f,g,h,x,K) \ - do \ - { \ - temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ - temp2 = S2(a) + F0((a),(b),(c)); \ - (d) += temp1; (h) = temp1 + temp2; \ - } while( 0 ) - - for( i = 0; i < 16; i++ ) - { - GET_UINT64_BE( W[i], data, i << 3 ); - } - - for( ; i < 80; i++ ) - { - W[i] = S1(W[i - 2]) + W[i - 7] + - S0(W[i - 15]) + W[i - 16]; - } - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - F = ctx->state[5]; - G = ctx->state[6]; - H = ctx->state[7]; - i = 0; - - do - { - P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; - P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; - P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; - P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; - P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; - P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; - P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; - P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; - } - while( i < 80 ); - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; - ctx->state[5] += F; - ctx->state[6] += G; - ctx->state[7] += H; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_process( mbedtls_sha512_context *ctx, - const unsigned char data[128] ) -{ - mbedtls_internal_sha512_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_SHA512_PROCESS_ALT */ - -/* - * SHA-512 process buffer - */ -int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - unsigned int left; - - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ilen == 0 ) - return( 0 ); - - left = (unsigned int) (ctx->total[0] & 0x7F); - fill = 128 - left; - - ctx->total[0] += (uint64_t) ilen; - - if( ctx->total[0] < (uint64_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 128 ) - { - if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 128; - ilen -= 128; - } - - if( ilen > 0 ) - memcpy( (void *) (ctx->buffer + left), input, ilen ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_update( mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha512_update_ret( ctx, input, ilen ); -} -#endif - -/* - * SHA-512 final digest - */ -int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, - unsigned char output[64] ) -{ - int ret; - unsigned used; - uint64_t high, low; - - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); - - /* - * Add padding: 0x80 then 0x00 until 16 bytes remain for the length - */ - used = ctx->total[0] & 0x7F; - - ctx->buffer[used++] = 0x80; - - if( used <= 112 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 112 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 128 - used ); - - if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 112 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 61 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT64_BE( high, ctx->buffer, 112 ); - PUT_UINT64_BE( low, ctx->buffer, 120 ); - - if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT64_BE( ctx->state[0], output, 0 ); - PUT_UINT64_BE( ctx->state[1], output, 8 ); - PUT_UINT64_BE( ctx->state[2], output, 16 ); - PUT_UINT64_BE( ctx->state[3], output, 24 ); - PUT_UINT64_BE( ctx->state[4], output, 32 ); - PUT_UINT64_BE( ctx->state[5], output, 40 ); - - if( ctx->is384 == 0 ) - { - PUT_UINT64_BE( ctx->state[6], output, 48 ); - PUT_UINT64_BE( ctx->state[7], output, 56 ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, - unsigned char output[64] ) -{ - mbedtls_sha512_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_SHA512_ALT */ - -/* - * output = SHA-512( input buffer ) - */ -int mbedtls_sha512_ret( const unsigned char *input, - size_t ilen, - unsigned char output[64], - int is384 ) -{ - int ret; - mbedtls_sha512_context ctx; - - SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); - SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); - - mbedtls_sha512_init( &ctx ); - - if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_sha512_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512( const unsigned char *input, - size_t ilen, - unsigned char output[64], - int is384 ) -{ - mbedtls_sha512_ret( input, ilen, output, is384 ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) - -/* - * FIPS-180-2 test vectors - */ -static const unsigned char sha512_test_buf[3][113] = -{ - { "abc" }, - { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, - { "" } -}; - -static const size_t sha512_test_buflen[3] = -{ - 3, 112, 1000 -}; - -static const unsigned char sha512_test_sum[6][64] = -{ - /* - * SHA-384 test vectors - */ - { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, - 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, - 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, - 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, - 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, - 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, - { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, - 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, - 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, - 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, - 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, - 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, - { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, - 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, - 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, - 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, - 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, - 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, - - /* - * SHA-512 test vectors - */ - { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, - 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, - 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, - 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, - 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, - 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, - 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, - 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, - { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, - 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, - 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, - 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, - 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, - 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, - 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, - 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, - { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, - 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, - 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, - 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, - 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, - 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, - 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, - 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } -}; - -/* - * Checkup routine - */ -int mbedtls_sha512_self_test( int verbose ) -{ - int i, j, k, buflen, ret = 0; - unsigned char *buf; - unsigned char sha512sum[64]; - mbedtls_sha512_context ctx; - - buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); - if( NULL == buf ) - { - if( verbose != 0 ) - mbedtls_printf( "Buffer allocation failed\n" ); - - return( 1 ); - } - - mbedtls_sha512_init( &ctx ); - - for( i = 0; i < 6; i++ ) - { - j = i % 3; - k = i < 3; - - if( verbose != 0 ) - mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); - - if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 ) - goto fail; - - if( j == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - { - ret = mbedtls_sha512_update_ret( &ctx, buf, buflen ); - if( ret != 0 ) - goto fail; - } - } - else - { - ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j], - sha512_test_buflen[j] ); - if( ret != 0 ) - goto fail; - } - - if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 ) - goto fail; - - if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - goto exit; - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - -exit: - mbedtls_sha512_free( &ctx ); - mbedtls_free( buf ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA512_C */ diff --git a/library/threading.c b/library/threading.c deleted file mode 100644 index 7c90c7c595..0000000000 --- a/library/threading.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Threading abstraction layer - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * config.h, which pulls in glibc's features.h. Harmless on other platforms. - */ -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112L -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_THREADING_C) - -#include "mbedtls/threading.h" - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) - -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) -#include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ - -#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ - -#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) -#define THREADING_USE_GMTIME -#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ - -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#if defined(MBEDTLS_THREADING_PTHREAD) -static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL ) - return; - - mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; -} - -static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || !mutex->is_valid ) - return; - - (void) pthread_mutex_destroy( &mutex->mutex ); - mutex->is_valid = 0; -} - -static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || ! mutex->is_valid ) - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); - - if( pthread_mutex_lock( &mutex->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - return( 0 ); -} - -static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || ! mutex->is_valid ) - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); - - if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - return( 0 ); -} - -void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; -void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; -int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; -int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; - -/* - * With phtreads we can statically initialize mutexes - */ -#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } - -#endif /* MBEDTLS_THREADING_PTHREAD */ - -#if defined(MBEDTLS_THREADING_ALT) -static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) -{ - ((void) mutex ); - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); -} -static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) -{ - ((void) mutex ); - return; -} - -void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; -void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; -int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; -int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; - -/* - * Set functions pointers and initialize global mutexes - */ -void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), - void (*mutex_free)( mbedtls_threading_mutex_t * ), - int (*mutex_lock)( mbedtls_threading_mutex_t * ), - int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) -{ - mbedtls_mutex_init = mutex_init; - mbedtls_mutex_free = mutex_free; - mbedtls_mutex_lock = mutex_lock; - mbedtls_mutex_unlock = mutex_unlock; - -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); -#endif -} - -/* - * Free global mutexes - */ -void mbedtls_threading_free_alt( void ) -{ -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); -#endif -} -#endif /* MBEDTLS_THREADING_ALT */ - -/* - * Define global mutexes - */ -#ifndef MUTEX_INIT -#define MUTEX_INIT -#endif -#if defined(MBEDTLS_FS_IO) -mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; -#endif -#if defined(THREADING_USE_GMTIME) -mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; -#endif - -#endif /* MBEDTLS_THREADING_C */ diff --git a/library/timing.c b/library/timing.c deleted file mode 100644 index 009516a6e3..0000000000 --- a/library/timing.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Portable interface to the CPU cycle counter - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif - -#if defined(MBEDTLS_TIMING_C) - -#include "mbedtls/timing.h" - -#if !defined(MBEDTLS_TIMING_ALT) - -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) -#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h" -#endif - -#ifndef asm -#define asm __asm -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -#include -#include - -struct _hr_time -{ - LARGE_INTEGER start; -}; - -#else - -#include -#include -#include -#include -#include - -struct _hr_time -{ - struct timeval start; -}; - -#endif /* _WIN32 && !EFIX64 && !EFI32 */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tsc; - __asm rdtsc - __asm mov [tsc], eax - return( tsc ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ - -/* some versions of mingw-64 have 32-bit longs even on x84_64 */ -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__i386__) || ( \ - ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long lo, hi; - asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); - return( lo ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __i386__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long lo, hi; - asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); - return( lo | ( hi << 32 ) ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && ( __amd64__ || __x86_64__ ) */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tbl, tbu0, tbu1; - - do - { - asm volatile( "mftbu %0" : "=r" (tbu0) ); - asm volatile( "mftb %0" : "=r" (tbl ) ); - asm volatile( "mftbu %0" : "=r" (tbu1) ); - } - while( tbu0 != tbu1 ); - - return( tbl ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && ( __powerpc__ || __ppc__ ) */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__sparc64__) - -#if defined(__OpenBSD__) -#warning OpenBSD does not allow access to tick register using software version instead -#else -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tick; - asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); - return( tick ); -} -#endif /* __OpenBSD__ */ -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __sparc64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tick; - asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); - asm volatile( "mov %%g1, %0" : "=r" (tick) ); - return( tick ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __sparc__ && !__sparc64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__alpha__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long cc; - asm volatile( "rpcc %0" : "=r" (cc) ); - return( cc & 0xFFFFFFFF ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __alpha__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__ia64__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long itc; - asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); - return( itc ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __ia64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ - !defined(EFIX64) && !defined(EFI32) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - LARGE_INTEGER offset; - - QueryPerformanceCounter( &offset ); - - return( (unsigned long)( offset.QuadPart ) ); -} -#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ - -#if !defined(HAVE_HARDCLOCK) - -#define HAVE_HARDCLOCK - -static int hardclock_init = 0; -static struct timeval tv_init; - -unsigned long mbedtls_timing_hardclock( void ) -{ - struct timeval tv_cur; - - if( hardclock_init == 0 ) - { - gettimeofday( &tv_init, NULL ); - hardclock_init = 1; - } - - gettimeofday( &tv_cur, NULL ); - return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 - + ( tv_cur.tv_usec - tv_init.tv_usec ) ); -} -#endif /* !HAVE_HARDCLOCK */ - -volatile int mbedtls_timing_alarmed = 0; - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) -{ - struct _hr_time *t = (struct _hr_time *) val; - - if( reset ) - { - QueryPerformanceCounter( &t->start ); - return( 0 ); - } - else - { - unsigned long delta; - LARGE_INTEGER now, hfreq; - QueryPerformanceCounter( &now ); - QueryPerformanceFrequency( &hfreq ); - delta = (unsigned long)( ( now.QuadPart - t->start.QuadPart ) * 1000ul - / hfreq.QuadPart ); - return( delta ); - } -} - -/* It's OK to use a global because alarm() is supposed to be global anyway */ -static DWORD alarmMs; - -static void TimerProc( void *TimerContext ) -{ - (void) TimerContext; - Sleep( alarmMs ); - mbedtls_timing_alarmed = 1; - /* _endthread will be called implicitly on return - * That ensures execution of thread funcition's epilogue */ -} - -void mbedtls_set_alarm( int seconds ) -{ - if( seconds == 0 ) - { - /* No need to create a thread for this simple case. - * Also, this shorcut is more reliable at least on MinGW32 */ - mbedtls_timing_alarmed = 1; - return; - } - - mbedtls_timing_alarmed = 0; - alarmMs = seconds * 1000; - (void) _beginthread( TimerProc, 0, NULL ); -} - -#else /* _WIN32 && !EFIX64 && !EFI32 */ - -unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) -{ - struct _hr_time *t = (struct _hr_time *) val; - - if( reset ) - { - gettimeofday( &t->start, NULL ); - return( 0 ); - } - else - { - unsigned long delta; - struct timeval now; - gettimeofday( &now, NULL ); - delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul - + ( now.tv_usec - t->start.tv_usec ) / 1000; - return( delta ); - } -} - -static void sighandler( int signum ) -{ - mbedtls_timing_alarmed = 1; - signal( signum, sighandler ); -} - -void mbedtls_set_alarm( int seconds ) -{ - mbedtls_timing_alarmed = 0; - signal( SIGALRM, sighandler ); - alarm( seconds ); - if( seconds == 0 ) - { - /* alarm(0) cancelled any previous pending alarm, but the - handler won't fire, so raise the flag straight away. */ - mbedtls_timing_alarmed = 1; - } -} - -#endif /* _WIN32 && !EFIX64 && !EFI32 */ - -/* - * Set delays to watch - */ -void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ) -{ - mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; - - ctx->int_ms = int_ms; - ctx->fin_ms = fin_ms; - - if( fin_ms != 0 ) - (void) mbedtls_timing_get_timer( &ctx->timer, 1 ); -} - -/* - * Get number of delays expired - */ -int mbedtls_timing_get_delay( void *data ) -{ - mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; - unsigned long elapsed_ms; - - if( ctx->fin_ms == 0 ) - return( -1 ); - - elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 ); - - if( elapsed_ms >= ctx->fin_ms ) - return( 2 ); - - if( elapsed_ms >= ctx->int_ms ) - return( 1 ); - - return( 0 ); -} - -#endif /* !MBEDTLS_TIMING_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Busy-waits for the given number of milliseconds. - * Used for testing mbedtls_timing_hardclock. - */ -static void busy_msleep( unsigned long msec ) -{ - struct mbedtls_timing_hr_time hires; - unsigned long i = 0; /* for busy-waiting */ - volatile unsigned long j; /* to prevent optimisation */ - - (void) mbedtls_timing_get_timer( &hires, 1 ); - - while( mbedtls_timing_get_timer( &hires, 0 ) < msec ) - i++; - - j = i; - (void) j; -} - -#define FAIL do \ - { \ - if( verbose != 0 ) \ - { \ - mbedtls_printf( "failed at line %d\n", __LINE__ ); \ - mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \ - cycles, ratio, millisecs, secs, hardfail, \ - (unsigned long) a, (unsigned long) b ); \ - mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \ - mbedtls_timing_get_timer( &hires, 0 ), \ - mbedtls_timing_get_timer( &ctx.timer, 0 ), \ - mbedtls_timing_get_delay( &ctx ) ); \ - } \ - return( 1 ); \ - } while( 0 ) - -/* - * Checkup routine - * - * Warning: this is work in progress, some tests may not be reliable enough - * yet! False positives may happen. - */ -int mbedtls_timing_self_test( int verbose ) -{ - unsigned long cycles = 0, ratio = 0; - unsigned long millisecs = 0, secs = 0; - int hardfail = 0; - struct mbedtls_timing_hr_time hires; - uint32_t a = 0, b = 0; - mbedtls_timing_delay_context ctx; - - if( verbose != 0 ) - mbedtls_printf( " TIMING tests note: will take some time!\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); - - { - secs = 1; - - (void) mbedtls_timing_get_timer( &hires, 1 ); - - mbedtls_set_alarm( (int) secs ); - while( !mbedtls_timing_alarmed ) - ; - - millisecs = mbedtls_timing_get_timer( &hires, 0 ); - - /* For some reason on Windows it looks like alarm has an extra delay - * (maybe related to creating a new thread). Allow some room here. */ - if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 ) - FAIL; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); - - { - a = 800; - b = 400; - mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */ - - busy_msleep( a - a / 4 ); /* T = a - a/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 0 ) - FAIL; - - busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 1 ) - FAIL; - - busy_msleep( b ); /* T = a + b + b/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 2 ) - FAIL; - } - - mbedtls_timing_set_delay( &ctx, 0, 0 ); - busy_msleep( 200 ); - if( mbedtls_timing_get_delay( &ctx ) != -1 ) - FAIL; - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " ); - - /* - * Allow one failure for possible counter wrapping. - * On a 4Ghz 32-bit machine the cycle counter wraps about once per second; - * since the whole test is about 10ms, it shouldn't happen twice in a row. - */ - -hard_test: - if( hardfail > 1 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed (ignored)\n" ); - - goto hard_test_done; - } - - /* Get a reference ratio cycles/ms */ - millisecs = 1; - cycles = mbedtls_timing_hardclock(); - busy_msleep( millisecs ); - cycles = mbedtls_timing_hardclock() - cycles; - ratio = cycles / millisecs; - - /* Check that the ratio is mostly constant */ - for( millisecs = 2; millisecs <= 4; millisecs++ ) - { - cycles = mbedtls_timing_hardclock(); - busy_msleep( millisecs ); - cycles = mbedtls_timing_hardclock() - cycles; - - /* Allow variation up to 20% */ - if( cycles / millisecs < ratio - ratio / 5 || - cycles / millisecs > ratio + ratio / 5 ) - { - hardfail++; - goto hard_test; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -hard_test_done: - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_TIMING_C */ diff --git a/library/xtea.c b/library/xtea.c deleted file mode 100644 index a33707bc17..0000000000 --- a/library/xtea.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * An 32-bit implementation of the XTEA algorithm - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_XTEA_C) - -#include "mbedtls/xtea.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_XTEA_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -void mbedtls_xtea_init( mbedtls_xtea_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_xtea_context ) ); -} - -void mbedtls_xtea_free( mbedtls_xtea_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_xtea_context ) ); -} - -/* - * XTEA key schedule - */ -void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ) -{ - int i; - - memset( ctx, 0, sizeof(mbedtls_xtea_context) ); - - for( i = 0; i < 4; i++ ) - { - GET_UINT32_BE( ctx->k[i], key, i << 2 ); - } -} - -/* - * XTEA encrypt function - */ -int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode, - const unsigned char input[8], unsigned char output[8]) -{ - uint32_t *k, v0, v1, i; - - k = ctx->k; - - GET_UINT32_BE( v0, input, 0 ); - GET_UINT32_BE( v1, input, 4 ); - - if( mode == MBEDTLS_XTEA_ENCRYPT ) - { - uint32_t sum = 0, delta = 0x9E3779B9; - - for( i = 0; i < 32; i++ ) - { - v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); - sum += delta; - v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); - } - } - else /* MBEDTLS_XTEA_DECRYPT */ - { - uint32_t delta = 0x9E3779B9, sum = delta * 32; - - for( i = 0; i < 32; i++ ) - { - v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); - sum -= delta; - v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); - } - } - - PUT_UINT32_BE( v0, output, 0 ); - PUT_UINT32_BE( v1, output, 4 ); - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * XTEA-CBC buffer encryption/decryption - */ -int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length, - unsigned char iv[8], const unsigned char *input, - unsigned char *output) -{ - int i; - unsigned char temp[8]; - - if( length % 8 ) - return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_XTEA_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 8 ); - mbedtls_xtea_crypt_ecb( ctx, mode, 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; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_xtea_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* !MBEDTLS_XTEA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * XTEA tests vectors (non-official) - */ - -static const unsigned char xtea_test_key[6][16] = -{ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char xtea_test_pt[6][8] = -{ - { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, - { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, - { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, - { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } -}; - -static const unsigned char xtea_test_ct[6][8] = -{ - { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, - { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, - { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, - { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } -}; - -/* - * Checkup routine - */ -int mbedtls_xtea_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char buf[8]; - mbedtls_xtea_context ctx; - - mbedtls_xtea_init( &ctx ); - for( i = 0; i < 6; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " XTEA test #%d: ", i + 1 ); - - memcpy( buf, xtea_test_pt[i], 8 ); - - mbedtls_xtea_setup( &ctx, xtea_test_key[i] ); - mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf ); - - if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_xtea_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_XTEA_C */