blob: 2e2d9dacb7c16653e0827eac6f314675474cccef [file] [log] [blame]
/*
* Embedded Linux library
*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <errno.h>
#include "util.h"
#include "tls.h"
#include "cipher.h"
#include "checksum.h"
#include "cert.h"
#include "tls-private.h"
/* RFC 7919, Section A.1 */
static const uint8_t tls_ffdhe2048_prime[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58,
0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1,
0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41,
0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9,
0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02,
0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61,
0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55,
0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35,
0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda,
0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35,
0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82,
0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb,
0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3,
0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19,
0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1,
0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61,
0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32,
0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73,
0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83,
0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa,
0x88, 0x6b, 0x42, 0x38, 0x61, 0x28, 0x5c, 0x97, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
};
/* RFC 7919, Section A.2 */
static const uint8_t tls_ffdhe3072_prime[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58,
0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1,
0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41,
0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9,
0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02,
0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61,
0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55,
0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35,
0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda,
0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35,
0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82,
0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb,
0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3,
0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19,
0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1,
0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61,
0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32,
0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73,
0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83,
0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa,
0x88, 0x6b, 0x42, 0x38, 0x61, 0x1f, 0xcf, 0xdc, 0xde, 0x35, 0x5b, 0x3b,
0x65, 0x19, 0x03, 0x5b, 0xbc, 0x34, 0xf4, 0xde, 0xf9, 0x9c, 0x02, 0x38,
0x61, 0xb4, 0x6f, 0xc9, 0xd6, 0xe6, 0xc9, 0x07, 0x7a, 0xd9, 0x1d, 0x26,
0x91, 0xf7, 0xf7, 0xee, 0x59, 0x8c, 0xb0, 0xfa, 0xc1, 0x86, 0xd9, 0x1c,
0xae, 0xfe, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xb4, 0x13, 0x0c, 0x93,
0xbc, 0x43, 0x79, 0x44, 0xf4, 0xfd, 0x44, 0x52, 0xe2, 0xd7, 0x4d, 0xd3,
0x64, 0xf2, 0xe2, 0x1e, 0x71, 0xf5, 0x4b, 0xff, 0x5c, 0xae, 0x82, 0xab,
0x9c, 0x9d, 0xf6, 0x9e, 0xe8, 0x6d, 0x2b, 0xc5, 0x22, 0x36, 0x3a, 0x0d,
0xab, 0xc5, 0x21, 0x97, 0x9b, 0x0d, 0xea, 0xda, 0x1d, 0xbf, 0x9a, 0x42,
0xd5, 0xc4, 0x48, 0x4e, 0x0a, 0xbc, 0xd0, 0x6b, 0xfa, 0x53, 0xdd, 0xef,
0x3c, 0x1b, 0x20, 0xee, 0x3f, 0xd5, 0x9d, 0x7c, 0x25, 0xe4, 0x1d, 0x2b,
0x66, 0xc6, 0x2e, 0x37, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
/* RFC 7919, Section A.3 */
static const uint8_t tls_ffdhe4096_prime[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58,
0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1,
0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41,
0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9,
0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02,
0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61,
0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55,
0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35,
0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda,
0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35,
0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82,
0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb,
0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3,
0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19,
0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1,
0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61,
0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32,
0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73,
0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83,
0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa,
0x88, 0x6b, 0x42, 0x38, 0x61, 0x1f, 0xcf, 0xdc, 0xde, 0x35, 0x5b, 0x3b,
0x65, 0x19, 0x03, 0x5b, 0xbc, 0x34, 0xf4, 0xde, 0xf9, 0x9c, 0x02, 0x38,
0x61, 0xb4, 0x6f, 0xc9, 0xd6, 0xe6, 0xc9, 0x07, 0x7a, 0xd9, 0x1d, 0x26,
0x91, 0xf7, 0xf7, 0xee, 0x59, 0x8c, 0xb0, 0xfa, 0xc1, 0x86, 0xd9, 0x1c,
0xae, 0xfe, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xb4, 0x13, 0x0c, 0x93,
0xbc, 0x43, 0x79, 0x44, 0xf4, 0xfd, 0x44, 0x52, 0xe2, 0xd7, 0x4d, 0xd3,
0x64, 0xf2, 0xe2, 0x1e, 0x71, 0xf5, 0x4b, 0xff, 0x5c, 0xae, 0x82, 0xab,
0x9c, 0x9d, 0xf6, 0x9e, 0xe8, 0x6d, 0x2b, 0xc5, 0x22, 0x36, 0x3a, 0x0d,
0xab, 0xc5, 0x21, 0x97, 0x9b, 0x0d, 0xea, 0xda, 0x1d, 0xbf, 0x9a, 0x42,
0xd5, 0xc4, 0x48, 0x4e, 0x0a, 0xbc, 0xd0, 0x6b, 0xfa, 0x53, 0xdd, 0xef,
0x3c, 0x1b, 0x20, 0xee, 0x3f, 0xd5, 0x9d, 0x7c, 0x25, 0xe4, 0x1d, 0x2b,
0x66, 0x9e, 0x1e, 0xf1, 0x6e, 0x6f, 0x52, 0xc3, 0x16, 0x4d, 0xf4, 0xfb,
0x79, 0x30, 0xe9, 0xe4, 0xe5, 0x88, 0x57, 0xb6, 0xac, 0x7d, 0x5f, 0x42,
0xd6, 0x9f, 0x6d, 0x18, 0x77, 0x63, 0xcf, 0x1d, 0x55, 0x03, 0x40, 0x04,
0x87, 0xf5, 0x5b, 0xa5, 0x7e, 0x31, 0xcc, 0x7a, 0x71, 0x35, 0xc8, 0x86,
0xef, 0xb4, 0x31, 0x8a, 0xed, 0x6a, 0x1e, 0x01, 0x2d, 0x9e, 0x68, 0x32,
0xa9, 0x07, 0x60, 0x0a, 0x91, 0x81, 0x30, 0xc4, 0x6d, 0xc7, 0x78, 0xf9,
0x71, 0xad, 0x00, 0x38, 0x09, 0x29, 0x99, 0xa3, 0x33, 0xcb, 0x8b, 0x7a,
0x1a, 0x1d, 0xb9, 0x3d, 0x71, 0x40, 0x00, 0x3c, 0x2a, 0x4e, 0xce, 0xa9,
0xf9, 0x8d, 0x0a, 0xcc, 0x0a, 0x82, 0x91, 0xcd, 0xce, 0xc9, 0x7d, 0xcf,
0x8e, 0xc9, 0xb5, 0x5a, 0x7f, 0x88, 0xa4, 0x6b, 0x4d, 0xb5, 0xa8, 0x51,
0xf4, 0x41, 0x82, 0xe1, 0xc6, 0x8a, 0x00, 0x7e, 0x5e, 0x65, 0x5f, 0x6a,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
/* RFC 7919, Section A.4 */
static const uint8_t tls_ffdhe6144_prime[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58,
0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1,
0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41,
0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9,
0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02,
0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61,
0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55,
0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35,
0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda,
0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35,
0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82,
0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb,
0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3,
0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19,
0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1,
0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61,
0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32,
0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73,
0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83,
0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa,
0x88, 0x6b, 0x42, 0x38, 0x61, 0x1f, 0xcf, 0xdc, 0xde, 0x35, 0x5b, 0x3b,
0x65, 0x19, 0x03, 0x5b, 0xbc, 0x34, 0xf4, 0xde, 0xf9, 0x9c, 0x02, 0x38,
0x61, 0xb4, 0x6f, 0xc9, 0xd6, 0xe6, 0xc9, 0x07, 0x7a, 0xd9, 0x1d, 0x26,
0x91, 0xf7, 0xf7, 0xee, 0x59, 0x8c, 0xb0, 0xfa, 0xc1, 0x86, 0xd9, 0x1c,
0xae, 0xfe, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xb4, 0x13, 0x0c, 0x93,
0xbc, 0x43, 0x79, 0x44, 0xf4, 0xfd, 0x44, 0x52, 0xe2, 0xd7, 0x4d, 0xd3,
0x64, 0xf2, 0xe2, 0x1e, 0x71, 0xf5, 0x4b, 0xff, 0x5c, 0xae, 0x82, 0xab,
0x9c, 0x9d, 0xf6, 0x9e, 0xe8, 0x6d, 0x2b, 0xc5, 0x22, 0x36, 0x3a, 0x0d,
0xab, 0xc5, 0x21, 0x97, 0x9b, 0x0d, 0xea, 0xda, 0x1d, 0xbf, 0x9a, 0x42,
0xd5, 0xc4, 0x48, 0x4e, 0x0a, 0xbc, 0xd0, 0x6b, 0xfa, 0x53, 0xdd, 0xef,
0x3c, 0x1b, 0x20, 0xee, 0x3f, 0xd5, 0x9d, 0x7c, 0x25, 0xe4, 0x1d, 0x2b,
0x66, 0x9e, 0x1e, 0xf1, 0x6e, 0x6f, 0x52, 0xc3, 0x16, 0x4d, 0xf4, 0xfb,
0x79, 0x30, 0xe9, 0xe4, 0xe5, 0x88, 0x57, 0xb6, 0xac, 0x7d, 0x5f, 0x42,
0xd6, 0x9f, 0x6d, 0x18, 0x77, 0x63, 0xcf, 0x1d, 0x55, 0x03, 0x40, 0x04,
0x87, 0xf5, 0x5b, 0xa5, 0x7e, 0x31, 0xcc, 0x7a, 0x71, 0x35, 0xc8, 0x86,
0xef, 0xb4, 0x31, 0x8a, 0xed, 0x6a, 0x1e, 0x01, 0x2d, 0x9e, 0x68, 0x32,
0xa9, 0x07, 0x60, 0x0a, 0x91, 0x81, 0x30, 0xc4, 0x6d, 0xc7, 0x78, 0xf9,
0x71, 0xad, 0x00, 0x38, 0x09, 0x29, 0x99, 0xa3, 0x33, 0xcb, 0x8b, 0x7a,
0x1a, 0x1d, 0xb9, 0x3d, 0x71, 0x40, 0x00, 0x3c, 0x2a, 0x4e, 0xce, 0xa9,
0xf9, 0x8d, 0x0a, 0xcc, 0x0a, 0x82, 0x91, 0xcd, 0xce, 0xc9, 0x7d, 0xcf,
0x8e, 0xc9, 0xb5, 0x5a, 0x7f, 0x88, 0xa4, 0x6b, 0x4d, 0xb5, 0xa8, 0x51,
0xf4, 0x41, 0x82, 0xe1, 0xc6, 0x8a, 0x00, 0x7e, 0x5e, 0x0d, 0xd9, 0x02,
0x0b, 0xfd, 0x64, 0xb6, 0x45, 0x03, 0x6c, 0x7a, 0x4e, 0x67, 0x7d, 0x2c,
0x38, 0x53, 0x2a, 0x3a, 0x23, 0xba, 0x44, 0x42, 0xca, 0xf5, 0x3e, 0xa6,
0x3b, 0xb4, 0x54, 0x32, 0x9b, 0x76, 0x24, 0xc8, 0x91, 0x7b, 0xdd, 0x64,
0xb1, 0xc0, 0xfd, 0x4c, 0xb3, 0x8e, 0x8c, 0x33, 0x4c, 0x70, 0x1c, 0x3a,
0xcd, 0xad, 0x06, 0x57, 0xfc, 0xcf, 0xec, 0x71, 0x9b, 0x1f, 0x5c, 0x3e,
0x4e, 0x46, 0x04, 0x1f, 0x38, 0x81, 0x47, 0xfb, 0x4c, 0xfd, 0xb4, 0x77,
0xa5, 0x24, 0x71, 0xf7, 0xa9, 0xa9, 0x69, 0x10, 0xb8, 0x55, 0x32, 0x2e,
0xdb, 0x63, 0x40, 0xd8, 0xa0, 0x0e, 0xf0, 0x92, 0x35, 0x05, 0x11, 0xe3,
0x0a, 0xbe, 0xc1, 0xff, 0xf9, 0xe3, 0xa2, 0x6e, 0x7f, 0xb2, 0x9f, 0x8c,
0x18, 0x30, 0x23, 0xc3, 0x58, 0x7e, 0x38, 0xda, 0x00, 0x77, 0xd9, 0xb4,
0x76, 0x3e, 0x4e, 0x4b, 0x94, 0xb2, 0xbb, 0xc1, 0x94, 0xc6, 0x65, 0x1e,
0x77, 0xca, 0xf9, 0x92, 0xee, 0xaa, 0xc0, 0x23, 0x2a, 0x28, 0x1b, 0xf6,
0xb3, 0xa7, 0x39, 0xc1, 0x22, 0x61, 0x16, 0x82, 0x0a, 0xe8, 0xdb, 0x58,
0x47, 0xa6, 0x7c, 0xbe, 0xf9, 0xc9, 0x09, 0x1b, 0x46, 0x2d, 0x53, 0x8c,
0xd7, 0x2b, 0x03, 0x74, 0x6a, 0xe7, 0x7f, 0x5e, 0x62, 0x29, 0x2c, 0x31,
0x15, 0x62, 0xa8, 0x46, 0x50, 0x5d, 0xc8, 0x2d, 0xb8, 0x54, 0x33, 0x8a,
0xe4, 0x9f, 0x52, 0x35, 0xc9, 0x5b, 0x91, 0x17, 0x8c, 0xcf, 0x2d, 0xd5,
0xca, 0xce, 0xf4, 0x03, 0xec, 0x9d, 0x18, 0x10, 0xc6, 0x27, 0x2b, 0x04,
0x5b, 0x3b, 0x71, 0xf9, 0xdc, 0x6b, 0x80, 0xd6, 0x3f, 0xdd, 0x4a, 0x8e,
0x9a, 0xdb, 0x1e, 0x69, 0x62, 0xa6, 0x95, 0x26, 0xd4, 0x31, 0x61, 0xc1,
0xa4, 0x1d, 0x57, 0x0d, 0x79, 0x38, 0xda, 0xd4, 0xa4, 0x0e, 0x32, 0x9c,
0xd0, 0xe4, 0x0e, 0x65, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
/* RFC 7919, Section A.5 */
static const uint8_t tls_ffdhe8192_prime[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58,
0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1,
0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41,
0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9,
0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02,
0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61,
0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55,
0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35,
0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda,
0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35,
0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82,
0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb,
0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3,
0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19,
0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1,
0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61,
0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32,
0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73,
0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83,
0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa,
0x88, 0x6b, 0x42, 0x38, 0x61, 0x1f, 0xcf, 0xdc, 0xde, 0x35, 0x5b, 0x3b,
0x65, 0x19, 0x03, 0x5b, 0xbc, 0x34, 0xf4, 0xde, 0xf9, 0x9c, 0x02, 0x38,
0x61, 0xb4, 0x6f, 0xc9, 0xd6, 0xe6, 0xc9, 0x07, 0x7a, 0xd9, 0x1d, 0x26,
0x91, 0xf7, 0xf7, 0xee, 0x59, 0x8c, 0xb0, 0xfa, 0xc1, 0x86, 0xd9, 0x1c,
0xae, 0xfe, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xb4, 0x13, 0x0c, 0x93,
0xbc, 0x43, 0x79, 0x44, 0xf4, 0xfd, 0x44, 0x52, 0xe2, 0xd7, 0x4d, 0xd3,
0x64, 0xf2, 0xe2, 0x1e, 0x71, 0xf5, 0x4b, 0xff, 0x5c, 0xae, 0x82, 0xab,
0x9c, 0x9d, 0xf6, 0x9e, 0xe8, 0x6d, 0x2b, 0xc5, 0x22, 0x36, 0x3a, 0x0d,
0xab, 0xc5, 0x21, 0x97, 0x9b, 0x0d, 0xea, 0xda, 0x1d, 0xbf, 0x9a, 0x42,
0xd5, 0xc4, 0x48, 0x4e, 0x0a, 0xbc, 0xd0, 0x6b, 0xfa, 0x53, 0xdd, 0xef,
0x3c, 0x1b, 0x20, 0xee, 0x3f, 0xd5, 0x9d, 0x7c, 0x25, 0xe4, 0x1d, 0x2b,
0x66, 0x9e, 0x1e, 0xf1, 0x6e, 0x6f, 0x52, 0xc3, 0x16, 0x4d, 0xf4, 0xfb,
0x79, 0x30, 0xe9, 0xe4, 0xe5, 0x88, 0x57, 0xb6, 0xac, 0x7d, 0x5f, 0x42,
0xd6, 0x9f, 0x6d, 0x18, 0x77, 0x63, 0xcf, 0x1d, 0x55, 0x03, 0x40, 0x04,
0x87, 0xf5, 0x5b, 0xa5, 0x7e, 0x31, 0xcc, 0x7a, 0x71, 0x35, 0xc8, 0x86,
0xef, 0xb4, 0x31, 0x8a, 0xed, 0x6a, 0x1e, 0x01, 0x2d, 0x9e, 0x68, 0x32,
0xa9, 0x07, 0x60, 0x0a, 0x91, 0x81, 0x30, 0xc4, 0x6d, 0xc7, 0x78, 0xf9,
0x71, 0xad, 0x00, 0x38, 0x09, 0x29, 0x99, 0xa3, 0x33, 0xcb, 0x8b, 0x7a,
0x1a, 0x1d, 0xb9, 0x3d, 0x71, 0x40, 0x00, 0x3c, 0x2a, 0x4e, 0xce, 0xa9,
0xf9, 0x8d, 0x0a, 0xcc, 0x0a, 0x82, 0x91, 0xcd, 0xce, 0xc9, 0x7d, 0xcf,
0x8e, 0xc9, 0xb5, 0x5a, 0x7f, 0x88, 0xa4, 0x6b, 0x4d, 0xb5, 0xa8, 0x51,
0xf4, 0x41, 0x82, 0xe1, 0xc6, 0x8a, 0x00, 0x7e, 0x5e, 0x0d, 0xd9, 0x02,
0x0b, 0xfd, 0x64, 0xb6, 0x45, 0x03, 0x6c, 0x7a, 0x4e, 0x67, 0x7d, 0x2c,
0x38, 0x53, 0x2a, 0x3a, 0x23, 0xba, 0x44, 0x42, 0xca, 0xf5, 0x3e, 0xa6,
0x3b, 0xb4, 0x54, 0x32, 0x9b, 0x76, 0x24, 0xc8, 0x91, 0x7b, 0xdd, 0x64,
0xb1, 0xc0, 0xfd, 0x4c, 0xb3, 0x8e, 0x8c, 0x33, 0x4c, 0x70, 0x1c, 0x3a,
0xcd, 0xad, 0x06, 0x57, 0xfc, 0xcf, 0xec, 0x71, 0x9b, 0x1f, 0x5c, 0x3e,
0x4e, 0x46, 0x04, 0x1f, 0x38, 0x81, 0x47, 0xfb, 0x4c, 0xfd, 0xb4, 0x77,
0xa5, 0x24, 0x71, 0xf7, 0xa9, 0xa9, 0x69, 0x10, 0xb8, 0x55, 0x32, 0x2e,
0xdb, 0x63, 0x40, 0xd8, 0xa0, 0x0e, 0xf0, 0x92, 0x35, 0x05, 0x11, 0xe3,
0x0a, 0xbe, 0xc1, 0xff, 0xf9, 0xe3, 0xa2, 0x6e, 0x7f, 0xb2, 0x9f, 0x8c,
0x18, 0x30, 0x23, 0xc3, 0x58, 0x7e, 0x38, 0xda, 0x00, 0x77, 0xd9, 0xb4,
0x76, 0x3e, 0x4e, 0x4b, 0x94, 0xb2, 0xbb, 0xc1, 0x94, 0xc6, 0x65, 0x1e,
0x77, 0xca, 0xf9, 0x92, 0xee, 0xaa, 0xc0, 0x23, 0x2a, 0x28, 0x1b, 0xf6,
0xb3, 0xa7, 0x39, 0xc1, 0x22, 0x61, 0x16, 0x82, 0x0a, 0xe8, 0xdb, 0x58,
0x47, 0xa6, 0x7c, 0xbe, 0xf9, 0xc9, 0x09, 0x1b, 0x46, 0x2d, 0x53, 0x8c,
0xd7, 0x2b, 0x03, 0x74, 0x6a, 0xe7, 0x7f, 0x5e, 0x62, 0x29, 0x2c, 0x31,
0x15, 0x62, 0xa8, 0x46, 0x50, 0x5d, 0xc8, 0x2d, 0xb8, 0x54, 0x33, 0x8a,
0xe4, 0x9f, 0x52, 0x35, 0xc9, 0x5b, 0x91, 0x17, 0x8c, 0xcf, 0x2d, 0xd5,
0xca, 0xce, 0xf4, 0x03, 0xec, 0x9d, 0x18, 0x10, 0xc6, 0x27, 0x2b, 0x04,
0x5b, 0x3b, 0x71, 0xf9, 0xdc, 0x6b, 0x80, 0xd6, 0x3f, 0xdd, 0x4a, 0x8e,
0x9a, 0xdb, 0x1e, 0x69, 0x62, 0xa6, 0x95, 0x26, 0xd4, 0x31, 0x61, 0xc1,
0xa4, 0x1d, 0x57, 0x0d, 0x79, 0x38, 0xda, 0xd4, 0xa4, 0x0e, 0x32, 0x9c,
0xcf, 0xf4, 0x6a, 0xaa, 0x36, 0xad, 0x00, 0x4c, 0xf6, 0x00, 0xc8, 0x38,
0x1e, 0x42, 0x5a, 0x31, 0xd9, 0x51, 0xae, 0x64, 0xfd, 0xb2, 0x3f, 0xce,
0xc9, 0x50, 0x9d, 0x43, 0x68, 0x7f, 0xeb, 0x69, 0xed, 0xd1, 0xcc, 0x5e,
0x0b, 0x8c, 0xc3, 0xbd, 0xf6, 0x4b, 0x10, 0xef, 0x86, 0xb6, 0x31, 0x42,
0xa3, 0xab, 0x88, 0x29, 0x55, 0x5b, 0x2f, 0x74, 0x7c, 0x93, 0x26, 0x65,
0xcb, 0x2c, 0x0f, 0x1c, 0xc0, 0x1b, 0xd7, 0x02, 0x29, 0x38, 0x88, 0x39,
0xd2, 0xaf, 0x05, 0xe4, 0x54, 0x50, 0x4a, 0xc7, 0x8b, 0x75, 0x82, 0x82,
0x28, 0x46, 0xc0, 0xba, 0x35, 0xc3, 0x5f, 0x5c, 0x59, 0x16, 0x0c, 0xc0,
0x46, 0xfd, 0x82, 0x51, 0x54, 0x1f, 0xc6, 0x8c, 0x9c, 0x86, 0xb0, 0x22,
0xbb, 0x70, 0x99, 0x87, 0x6a, 0x46, 0x0e, 0x74, 0x51, 0xa8, 0xa9, 0x31,
0x09, 0x70, 0x3f, 0xee, 0x1c, 0x21, 0x7e, 0x6c, 0x38, 0x26, 0xe5, 0x2c,
0x51, 0xaa, 0x69, 0x1e, 0x0e, 0x42, 0x3c, 0xfc, 0x99, 0xe9, 0xe3, 0x16,
0x50, 0xc1, 0x21, 0x7b, 0x62, 0x48, 0x16, 0xcd, 0xad, 0x9a, 0x95, 0xf9,
0xd5, 0xb8, 0x01, 0x94, 0x88, 0xd9, 0xc0, 0xa0, 0xa1, 0xfe, 0x30, 0x75,
0xa5, 0x77, 0xe2, 0x31, 0x83, 0xf8, 0x1d, 0x4a, 0x3f, 0x2f, 0xa4, 0x57,
0x1e, 0xfc, 0x8c, 0xe0, 0xba, 0x8a, 0x4f, 0xe8, 0xb6, 0x85, 0x5d, 0xfe,
0x72, 0xb0, 0xa6, 0x6e, 0xde, 0xd2, 0xfb, 0xab, 0xfb, 0xe5, 0x8a, 0x30,
0xfa, 0xfa, 0xbe, 0x1c, 0x5d, 0x71, 0xa8, 0x7e, 0x2f, 0x74, 0x1e, 0xf8,
0xc1, 0xfe, 0x86, 0xfe, 0xa6, 0xbb, 0xfd, 0xe5, 0x30, 0x67, 0x7f, 0x0d,
0x97, 0xd1, 0x1d, 0x49, 0xf7, 0xa8, 0x44, 0x3d, 0x08, 0x22, 0xe5, 0x06,
0xa9, 0xf4, 0x61, 0x4e, 0x01, 0x1e, 0x2a, 0x94, 0x83, 0x8f, 0xf8, 0x8c,
0xd6, 0x8c, 0x8b, 0xb7, 0xc5, 0xc6, 0x42, 0x4c, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
};
/* RFC 3526, Section 3 */
static const uint8_t tls_dh14_prime[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2,
0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1,
0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6,
0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,
0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45,
0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9,
0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,
0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11,
0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d,
0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, 0x98, 0xda, 0x48, 0x36,
0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f,
0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56,
0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d,
0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, 0xf1, 0x74, 0x6c, 0x08,
0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46, 0x2e, 0x36, 0xce, 0x3b,
0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03, 0x9b, 0x27, 0x83, 0xa2,
0xec, 0x07, 0xa2, 0x8f, 0xb5, 0xc5, 0x5d, 0xf0, 0x6f, 0x4c, 0x52, 0xc9,
0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7c,
0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18, 0x98, 0xfa, 0x05, 0x10,
0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xac, 0xaa, 0x68, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
};
static const struct tls_named_group tls_group_pref[] = {
{ "secp256r1", 23, TLS_GROUP_TYPE_EC },
{ "secp384r1", 24, TLS_GROUP_TYPE_EC },
{
"ffdhe2048", 256, TLS_GROUP_TYPE_FF,
.ff = {
.prime = tls_ffdhe2048_prime,
.prime_len = sizeof(tls_ffdhe2048_prime),
.generator = 2,
},
},
{
"ffdhe3072", 257, TLS_GROUP_TYPE_FF,
.ff = {
.prime = tls_ffdhe3072_prime,
.prime_len = sizeof(tls_ffdhe3072_prime),
.generator = 2,
},
},
{
"ffdhe4096", 258, TLS_GROUP_TYPE_FF,
.ff = {
.prime = tls_ffdhe4096_prime,
.prime_len = sizeof(tls_ffdhe4096_prime),
.generator = 2,
},
},
{
"ffdhe6144", 259, TLS_GROUP_TYPE_FF,
.ff = {
.prime = tls_ffdhe6144_prime,
.prime_len = sizeof(tls_ffdhe6144_prime),
.generator = 2,
},
},
{
"ffdhe8192", 260, TLS_GROUP_TYPE_FF,
.ff = {
.prime = tls_ffdhe8192_prime,
.prime_len = sizeof(tls_ffdhe8192_prime),
.generator = 2,
},
},
};
/*
* For now hardcode a default group for non-RFC7919 clients - same group
* as some other TLS servers use, which is actually a downside because the
* more common the group parameters are the less secure they are assumed
* to be, but it is also a test that the group is sufficiently good.
*
* Eventually we need to make this configurable so that a unique
* likely-prime number generated by either 'openssl dhparam' or
* 'ssh-keygen -G' can be set, or parse /etc/ssh/moduli to select
* a random pre-generated FFDH group each time.
*/
static const struct tls_named_group tls_default_ffdh_group = {
"RFC3526/Oakley Group 14", 0, TLS_GROUP_TYPE_FF,
.ff = {
.prime = tls_dh14_prime,
.prime_len = sizeof(tls_dh14_prime),
.generator = 2,
},
};
/* RFC 8422, Section 5.1 + RFC 7919 */
static ssize_t tls_elliptic_curves_client_write(struct l_tls *tls,
uint8_t *buf, size_t len)
{
uint8_t *ptr = buf;
unsigned int i;
if (len < 2 + L_ARRAY_SIZE(tls_group_pref) * 2)
return -ENOMEM;
l_put_be16(L_ARRAY_SIZE(tls_group_pref) * 2, ptr);
ptr += 2;
for (i = 0; i < L_ARRAY_SIZE(tls_group_pref); i++) {
l_put_be16(tls_group_pref[i].id, ptr);
ptr += 2;
}
return ptr - buf;
}
static bool tls_elliptic_curves_client_handle(struct l_tls *tls,
const uint8_t *buf, size_t len)
{
bool ffdh_offered = false;
if (len < 2)
return false;
if (l_get_be16(buf) != len - 2 || (len & 1))
return false;
buf += 2;
len -= 2;
/*
* We select one group for DH and one group for ECDH and we'll
* let the cipher suite selection logic decide which one is actually
* used. It will take into account the client's cipher suite
* preference but it could just as well look at the strengths of
* the groups chosen. This is not done for simplicity but RFC 7919
* suggests the Supported Groups should actually overrule the
* cipher suite preference list in case of a conflict:
* "A server that encounters such a contradiction when selecting
* between an ECDHE or FFDHE key exchange mechanism while trying
* to respect client preferences SHOULD give priority to the
* Supported Groups extension (...) but MAY resolve the
* contradiction any way it sees fit."
*
* Not implemented: "If a non-anonymous FFDHE cipher suite is
* selected and the TLS client has used this extension to offer
* an FFDHE group of comparable or greater strength than the server's
* public key, the server SHOULD select an FFDHE group at least
* as strong as the server's public key."
*/
while (len) {
unsigned int i;
uint16_t id;
const struct tls_named_group *group = NULL;
id = l_get_be16(buf);
buf += 2;
len -= 2;
if (id >> 8 == 1) /* RFC 7919 ids */
ffdh_offered = true;
for (i = 0; i < L_ARRAY_SIZE(tls_group_pref); i++)
if (tls_group_pref[i].id == id) {
group = &tls_group_pref[i];
break;
}
if (!group)
continue;
switch (group->type) {
case TLS_GROUP_TYPE_EC:
if (!tls->negotiated_curve)
tls->negotiated_curve = group;
break;
case TLS_GROUP_TYPE_FF:
if (!tls->negotiated_ff_group)
tls->negotiated_ff_group = group;
break;
}
}
/*
* Note we need to treat DH slightly differently from ECDH groups
* here because the extension is defined in RFC 8422 and if the
* client offers no elliptic curves we can't use ECDH at all:
* "If a server (...) is unable to complete the ECC handshake while
* restricting itself to the enumerated curves (...), it MUST NOT
* negotiate the use of an ECC cipher suite. Depending on what
* other cipher suites are proposed by the client and supported by
* the server, this may result in a fatal handshake failure alert
* due to the lack of common cipher suites."
*
* On the other hand if the client offers no FFDH groups we can
* only assume the client is okay with us picking a group. Note
* the "includes any FFDHE group" part in RFC 7919 Section 4:
* "If a compatible TLS server receives a Supported Groups
* extension from a client that includes any FFDHE group (i.e.,
* any codepoint between 256 and 511, inclusive, even if unknown
* to the server), and if none of the client-proposed FFDHE groups
* are known and acceptable to the server, then the server MUST
* NOT select an FFDHE cipher suite."
*/
if (tls->negotiated_curve)
TLS_DEBUG("Negotiated %s", tls->negotiated_curve->name);
else
TLS_DEBUG("non-fatal: No common supported elliptic curves "
"for ECDHE");
if (tls->negotiated_ff_group)
TLS_DEBUG("Negotiated %s", tls->negotiated_ff_group->name);
else if (ffdh_offered)
TLS_DEBUG("non-fatal: No common supported finite-field groups "
"for DHE");
else
tls->negotiated_ff_group = &tls_default_ffdh_group;
return true;
}
static bool tls_elliptic_curves_client_absent(struct l_tls *tls)
{
unsigned int i;
for (i = 0; i < L_ARRAY_SIZE(tls_group_pref); i++)
if (tls_group_pref[i].type == TLS_GROUP_TYPE_EC) {
tls->negotiated_curve = &tls_group_pref[i];
break;
}
tls->negotiated_ff_group = &tls_default_ffdh_group;
return true;
}
static bool tls_ec_point_formats_client_handle(struct l_tls *tls,
const uint8_t *buf, size_t len)
{
if (len < 2)
return false;
if (buf[0] != len - 1)
return false;
if (!memchr(buf + 1, 0, len - 1)) {
TLS_DEBUG("Uncompressed point format missing");
return false;
}
return true;
}
/*
* For compatibility with clients respond to a valid Client Hello Supported
* Point Formats extension with the hardcoded confirmation that we do
* support the single valid point format. As a client we never send this
* extension so we never have to handle a server response to it either.
*/
static ssize_t tls_ec_point_formats_server_write(struct l_tls *tls,
uint8_t *buf, size_t len)
{
if (len < 2)
return -ENOMEM;
buf[0] = 0x01; /* ec_point_format_list length */
buf[1] = 0x00; /* uncompressed */
return 2;
}
/*
* This is used to append the list of signature algorithm and hash type
* combinations we support to the Signature Algorithms client hello
* extension (on the client) and the Certificate Request message (on the
* server). In both cases we need to list the algorithms we support for
* two use cases: certificate chain verification and signing/verifying
* Server Key Exchange params (server->client) or Certificate Verify
* data (client->server).
*
* For the server side RFC 5462, Section 7.4.1.4.1 says:
* "If the client [...] is willing to use them for verifying
* messages sent by the server, i.e., server certificates and
* server key exchange [...] it MUST send the
* signature_algorithms extension, listing the algorithms it
* is willing to accept."
*
* As for the certificate chains we mostly rely on the kernel to do
* this so when we receive the list we do not currently verify the
* that the whole chain uses only algorithms from the list on either
* side (TODO). But we know that the chain verification in the kernel
* can use a superset of the hash algorithms l_checksum supports.
* For the Server Key Exchange and Certificate Verify signatures we
* use l_checksum but we need to map the TLS-specific hash IDs to
* enum l_checksum_type using the tls_handshake_hash_data list in
* signature->sign() and signature->verify(), so we use
* tls_handshake_hash_data as the definitive list of allowed hash
* algorithms.
*
* Our supported signature algorithms can work with any hash type so we
* basically have to send all possible combinations of the signature
* algorithm IDs from the supported cipher suites (except anonymous)
* with the hash algorithms we can use for signature verification,
* i.e. those in the tls_handshake_hash_data table.
*/
ssize_t tls_write_signature_algorithms(struct l_tls *tls,
uint8_t *buf, size_t len)
{
uint8_t *ptr = buf;
unsigned int i, j;
struct tls_cipher_suite **suite;
uint8_t sig_alg_ids[16];
uint8_t hash_ids[16];
unsigned int sig_alg_cnt = 0;
unsigned int hash_cnt = 0;
for (suite = tls->cipher_suite_pref_list; *suite; suite++) {
uint8_t id;
if (!(*suite)->signature)
continue;
id = (*suite)->signature->id;
if (memchr(sig_alg_ids, id, sig_alg_cnt))
continue;
if (!tls_cipher_suite_is_compatible(tls, *suite, NULL))
continue;
if (sig_alg_cnt >= sizeof(sig_alg_ids))
return -ENOMEM;
sig_alg_ids[sig_alg_cnt++] = id;
}
for (i = 0; i < __HANDSHAKE_HASH_COUNT; i++) {
const struct tls_hash_algorithm *hash =
&tls_handshake_hash_data[i];
bool supported;
/*
* The hash types in the Signature Algorithms extension are
* all supported hashes but the ones in the Certificate
* Request (server->client) must be in the set for which we
* maintain handshake message hashes because that is going
* to be used in Certificate Verify.
*/
if (tls->server)
supported = !!tls->handshake_hash[i];
else
supported = l_checksum_is_supported(hash->l_id, false);
if (supported)
hash_ids[hash_cnt++] = hash->tls_id;
}
if (len < 2 + sig_alg_cnt * hash_cnt * 2)
return -ENOMEM;
l_put_be16(sig_alg_cnt * hash_cnt * 2, ptr);
ptr += 2;
for (i = 0; i < sig_alg_cnt; i++)
for (j = 0; j < hash_cnt; j++) {
*ptr++ = hash_ids[j];
*ptr++ = sig_alg_ids[i];
}
return ptr - buf;
}
ssize_t tls_parse_signature_algorithms(struct l_tls *tls,
const uint8_t *buf, size_t len)
{
const uint8_t *ptr = buf;
enum handshake_hash_type first_supported, hash;
const struct tls_hash_algorithm *preferred;
struct tls_cipher_suite **suite;
uint8_t sig_alg_ids[16];
unsigned int sig_alg_cnt = 0;
/*
* This only makes sense as a variable-length field, assume
* there's a typo in RFC5246 7.4.4 here.
*/
if (len < 4)
return -EINVAL;
if (l_get_be16(ptr) > len - 2)
return -EINVAL;
len = l_get_be16(ptr);
ptr += 2;
if (len & 1)
return -EINVAL;
for (suite = tls->cipher_suite_pref_list; *suite; suite++) {
uint8_t id;
if (!(*suite)->signature)
continue;
id = (*suite)->signature->id;
if (memchr(sig_alg_ids, id, sig_alg_cnt))
continue;
if (!tls_cipher_suite_is_compatible(tls, *suite, NULL))
continue;
if (sig_alg_cnt >= sizeof(sig_alg_ids))
return -ENOMEM;
sig_alg_ids[sig_alg_cnt++] = id;
}
/*
* In 1.2 we force our preference for SHA256/SHA384 (depending on
* cipher suite's PRF hmac) if it is supported by the peer because
* that must be supported anyway for the PRF and the Finished hash
* meaning that we only need to keep one hash instead of two.
* If not available fall back to the first common hash algorithm.
*/
first_supported = -1;
if (tls->prf_hmac)
preferred = tls->prf_hmac;
else
preferred = &tls_handshake_hash_data[HANDSHAKE_HASH_SHA256];
while (len) {
uint8_t hash_id = *ptr++;
uint8_t sig_alg_id = *ptr++;
bool supported;
len -= 2;
/* Ignore hash types for signatures other than ours */
if (tls->pending.cipher_suite &&
(!tls->pending.cipher_suite->signature ||
tls->pending.cipher_suite->signature->id !=
sig_alg_id))
continue;
else if (!tls->pending.cipher_suite &&
!memchr(sig_alg_ids, sig_alg_id, sig_alg_cnt))
continue;
if (hash_id == preferred->tls_id) {
for (hash = 0; hash < __HANDSHAKE_HASH_COUNT; hash++)
if (&tls_handshake_hash_data[hash] == preferred)
break;
break;
}
if ((int) first_supported != -1)
continue;
for (hash = 0; hash < __HANDSHAKE_HASH_COUNT; hash++)
if (hash_id == tls_handshake_hash_data[hash].tls_id)
break;
if (hash == __HANDSHAKE_HASH_COUNT)
continue;
if (tls->server)
supported = l_checksum_is_supported(
tls_handshake_hash_data[hash].l_id,
false);
else
supported = !!tls->handshake_hash[hash];
if (supported)
first_supported = hash;
}
if (len)
tls->signature_hash = hash;
else if ((int) first_supported != -1)
tls->signature_hash = first_supported;
else
return -ENOTSUP;
return ptr + len - buf;
}
/* RFC 5462, Section 7.4.1.4.1 */
static ssize_t tls_signature_algorithms_client_write(struct l_tls *tls,
uint8_t *buf, size_t len)
{
/*
* "Note: this extension is not meaningful for TLS versions
* prior to 1.2. Clients MUST NOT offer it if they are offering
* prior versions."
*/
if (tls->max_version < L_TLS_V12)
return -ENOMSG;
return tls_write_signature_algorithms(tls, buf, len);
}
static bool tls_signature_algorithms_client_handle(struct l_tls *tls,
const uint8_t *buf, size_t len)
{
ssize_t ret;
/*
* "However, even if clients do offer it, the rules specified in
* [TLSEXT] require servers to ignore extensions they do not
* understand."
*/
if (tls->max_version < L_TLS_V12)
return true;
ret = tls_parse_signature_algorithms(tls, buf, len);
if (ret == -ENOTSUP)
TLS_DEBUG("No common signature algorithms");
/*
* TODO: also check our certificate chain against the parsed
* signature algorithms.
*/
return ret == (ssize_t) len;
}
static bool tls_signature_algorithms_client_absent(struct l_tls *tls)
{
/*
* "If the client does not send the signature_algorithms extension,
* the server MUST do the following:
* - [...] behave as if client had sent the value {sha1,rsa}.
* - [...] behave as if client had sent the value {sha1,dsa}.
* - [...] behave as if client had sent the value {sha1,ecdsa}.
*/
if (tls->max_version >= L_TLS_V12)
tls->signature_hash = HANDSHAKE_HASH_SHA1;
return true;
}
const struct tls_hello_extension tls_extensions[] = {
{
"Supported Groups", "elliptic_curves", 10,
tls_elliptic_curves_client_write,
tls_elliptic_curves_client_handle,
tls_elliptic_curves_client_absent,
NULL, NULL, NULL,
},
{
"Supported Point Formats", "ec_point_formats", 11,
NULL,
tls_ec_point_formats_client_handle,
NULL,
tls_ec_point_formats_server_write,
NULL, NULL,
},
{
"Signature Algorithms", "signature_algoritms", 13,
tls_signature_algorithms_client_write,
tls_signature_algorithms_client_handle,
tls_signature_algorithms_client_absent,
NULL, NULL, NULL,
},
{}
};
const struct tls_named_group *tls_find_group(uint16_t id)
{
unsigned int i;
for (i = 0; i < L_ARRAY_SIZE(tls_group_pref); i++)
if (tls_group_pref[i].id == id)
return &tls_group_pref[i];
return NULL;
}
const struct tls_named_group *tls_find_ff_group(const uint8_t *prime,
size_t prime_len,
const uint8_t *generator,
size_t generator_len)
{
unsigned int i;
if (generator_len != 1)
return NULL;
for (i = 0; i < L_ARRAY_SIZE(tls_group_pref); i++) {
const struct tls_named_group *g = &tls_group_pref[i];
if (g->type != TLS_GROUP_TYPE_FF)
continue;
if (g->ff.prime_len != prime_len ||
memcmp(prime, g->ff.prime, prime_len))
continue;
if (g->ff.generator != *generator)
continue;
return g;
}
return NULL;
}