Annotation of embedaddon/strongswan/src/libtls/tls_crypto.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2010-2014 Martin Willi
        !             3:  * Copyright (C) 2010-2014 revosec AG
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #include "tls_crypto.h"
        !            17: 
        !            18: #include <utils/debug.h>
        !            19: #include <plugins/plugin_feature.h>
        !            20: 
        !            21: ENUM_BEGIN(tls_cipher_suite_names, TLS_NULL_WITH_NULL_NULL,
        !            22:                                                                   TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
        !            23:        "TLS_NULL_WITH_NULL_NULL",
        !            24:        "TLS_RSA_WITH_NULL_MD5",
        !            25:        "TLS_RSA_WITH_NULL_SHA",
        !            26:        "TLS_RSA_EXPORT_WITH_RC4_40_MD5",
        !            27:        "TLS_RSA_WITH_RC4_128_MD5",
        !            28:        "TLS_RSA_WITH_RC4_128_SHA",
        !            29:        "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
        !            30:        "TLS_RSA_WITH_IDEA_CBC_SHA",
        !            31:        "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
        !            32:        "TLS_RSA_WITH_DES_CBC_SHA",
        !            33:        "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
        !            34:        "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA",
        !            35:        "TLS_DH_DSS_WITH_DES_CBC_SHA",
        !            36:        "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA",
        !            37:        "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA",
        !            38:        "TLS_DH_RSA_WITH_DES_CBC_SHA",
        !            39:        "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA",
        !            40:        "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
        !            41:        "TLS_DHE_DSS_WITH_DES_CBC_SHA",
        !            42:        "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
        !            43:        "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
        !            44:        "TLS_DHE_RSA_WITH_DES_CBC_SHA",
        !            45:        "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
        !            46:        "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5",
        !            47:        "TLS_DH_anon_WITH_RC4_128_MD5",
        !            48:        "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
        !            49:        "TLS_DH_anon_WITH_DES_CBC_SHA",
        !            50:        "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA");
        !            51: ENUM_NEXT(tls_cipher_suite_names, TLS_KRB5_WITH_DES_CBC_SHA,
        !            52:                                                                  TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
        !            53:                                                                  TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
        !            54:        "TLS_KRB5_WITH_DES_CBC_SHA",
        !            55:        "TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
        !            56:        "TLS_KRB5_WITH_RC4_128_SHA",
        !            57:        "TLS_KRB5_WITH_IDEA_CBC_SHA",
        !            58:        "TLS_KRB5_WITH_DES_CBC_MD5",
        !            59:        "TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
        !            60:        "TLS_KRB5_WITH_RC4_128_MD5",
        !            61:        "TLS_KRB5_WITH_IDEA_CBC_MD5",
        !            62:        "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
        !            63:        "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA",
        !            64:        "TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
        !            65:        "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
        !            66:        "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5",
        !            67:        "TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
        !            68:        "TLS_PSK_WITH_NULL_SHA",
        !            69:        "TLS_DHE_PSK_WITH_NULL_SHA",
        !            70:        "TLS_RSA_PSK_WITH_NULL_SHA",
        !            71:        "TLS_RSA_WITH_AES_128_CBC_SHA",
        !            72:        "TLS_DH_DSS_WITH_AES_128_CBC_SHA",
        !            73:        "TLS_DH_RSA_WITH_AES_128_CBC_SHA",
        !            74:        "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
        !            75:        "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
        !            76:        "TLS_DH_anon_WITH_AES_128_CBC_SHA",
        !            77:        "TLS_RSA_WITH_AES_256_CBC_SHA",
        !            78:        "TLS_DH_DSS_WITH_AES_256_CBC_SHA",
        !            79:        "TLS_DH_RSA_WITH_AES_256_CBC_SHA",
        !            80:        "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
        !            81:        "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
        !            82:        "TLS_DH_anon_WITH_AES_256_CBC_SHA",
        !            83:        "TLS_RSA_WITH_NULL_SHA256",
        !            84:        "TLS_RSA_WITH_AES_128_CBC_SHA256",
        !            85:        "TLS_RSA_WITH_AES_256_CBC_SHA256",
        !            86:        "TLS_DH_DSS_WITH_AES_128_CBC_SHA256",
        !            87:        "TLS_DH_RSA_WITH_AES_128_CBC_SHA256",
        !            88:        "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
        !            89:        "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA",
        !            90:        "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA",
        !            91:        "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA",
        !            92:        "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA",
        !            93:        "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA",
        !            94:        "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA");
        !            95: ENUM_NEXT(tls_cipher_suite_names, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
        !            96:                                                                  TLS_DH_anon_WITH_AES_256_CBC_SHA256,
        !            97:                                                                  TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
        !            98:        "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
        !            99:        "TLS_DH_DSS_WITH_AES_256_CBC_SHA256",
        !           100:        "TLS_DH_RSA_WITH_AES_256_CBC_SHA256",
        !           101:        "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
        !           102:        "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
        !           103:        "TLS_DH_anon_WITH_AES_128_CBC_SHA256",
        !           104:        "TLS_DH_anon_WITH_AES_256_CBC_SHA256");
        !           105: ENUM_NEXT(tls_cipher_suite_names, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
        !           106:                                                                  TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
        !           107:                                                                  TLS_DH_anon_WITH_AES_256_CBC_SHA256,
        !           108:        "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA",
        !           109:        "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA",
        !           110:        "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA",
        !           111:        "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA",
        !           112:        "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA",
        !           113:        "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA",
        !           114:        "TLS_PSK_WITH_RC4_128_SHA",
        !           115:        "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
        !           116:        "TLS_PSK_WITH_AES_128_CBC_SHA",
        !           117:        "TLS_PSK_WITH_AES_256_CBC_SHA",
        !           118:        "TLS_DHE_PSK_WITH_RC4_128_SHA",
        !           119:        "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA",
        !           120:        "TLS_DHE_PSK_WITH_AES_128_CBC_SHA",
        !           121:        "TLS_DHE_PSK_WITH_AES_256_CBC_SHA",
        !           122:        "TLS_RSA_PSK_WITH_RC4_128_SHA",
        !           123:        "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA",
        !           124:        "TLS_RSA_PSK_WITH_AES_128_CBC_SHA",
        !           125:        "TLS_RSA_PSK_WITH_AES_256_CBC_SHA",
        !           126:        "TLS_RSA_WITH_SEED_CBC_SHA",
        !           127:        "TLS_DH_DSS_WITH_SEED_CBC_SHA",
        !           128:        "TLS_DH_RSA_WITH_SEED_CBC_SHA",
        !           129:        "TLS_DHE_DSS_WITH_SEED_CBC_SHA",
        !           130:        "TLS_DHE_RSA_WITH_SEED_CBC_SHA",
        !           131:        "TLS_DH_anon_WITH_SEED_CBC_SHA",
        !           132:        "TLS_RSA_WITH_AES_128_GCM_SHA256",
        !           133:        "TLS_RSA_WITH_AES_256_GCM_SHA384",
        !           134:        "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
        !           135:        "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
        !           136:        "TLS_DH_RSA_WITH_AES_128_GCM_SHA256",
        !           137:        "TLS_DH_RSA_WITH_AES_256_GCM_SHA384",
        !           138:        "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
        !           139:        "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
        !           140:        "TLS_DH_DSS_WITH_AES_128_GCM_SHA256",
        !           141:        "TLS_DH_DSS_WITH_AES_256_GCM_SHA384",
        !           142:        "TLS_DH_anon_WITH_AES_128_GCM_SHA256",
        !           143:        "TLS_DH_anon_WITH_AES_256_GCM_SHA384",
        !           144:        "TLS_PSK_WITH_AES_128_GCM_SHA256",
        !           145:        "TLS_PSK_WITH_AES_256_GCM_SHA384",
        !           146:        "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256",
        !           147:        "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384",
        !           148:        "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256",
        !           149:        "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384",
        !           150:        "TLS_PSK_WITH_AES_128_CBC_SHA256",
        !           151:        "TLS_PSK_WITH_AES_256_CBC_SHA384",
        !           152:        "TLS_PSK_WITH_NULL_SHA256",
        !           153:        "TLS_PSK_WITH_NULL_SHA384",
        !           154:        "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256",
        !           155:        "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384",
        !           156:        "TLS_DHE_PSK_WITH_NULL_SHA256",
        !           157:        "TLS_DHE_PSK_WITH_NULL_SHA384",
        !           158:        "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256",
        !           159:        "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384",
        !           160:        "TLS_RSA_PSK_WITH_NULL_SHA256",
        !           161:        "TLS_RSA_PSK_WITH_NULL_SHA384",
        !           162:        "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256",
        !           163:        "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256",
        !           164:        "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256",
        !           165:        "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256",
        !           166:        "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256",
        !           167:        "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256",
        !           168:        "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256",
        !           169:        "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256",
        !           170:        "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256",
        !           171:        "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256",
        !           172:        "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256",
        !           173:        "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256");
        !           174: ENUM_NEXT(tls_cipher_suite_names, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
        !           175:                                                                  TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
        !           176:                                                                  TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
        !           177:        "TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
        !           178: ENUM_NEXT(tls_cipher_suite_names, TLS_ECDH_ECDSA_WITH_NULL_SHA,
        !           179:                                                                  TLS_ECDHE_PSK_WITH_NULL_SHA384,
        !           180:                                                                  TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
        !           181:        "TLS_ECDH_ECDSA_WITH_NULL_SHA",
        !           182:        "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
        !           183:        "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
        !           184:        "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
        !           185:        "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
        !           186:        "TLS_ECDHE_ECDSA_WITH_NULL_SHA",
        !           187:        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
        !           188:        "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
        !           189:        "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
        !           190:        "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
        !           191:        "TLS_ECDH_RSA_WITH_NULL_SHA",
        !           192:        "TLS_ECDH_RSA_WITH_RC4_128_SHA",
        !           193:        "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
        !           194:        "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
        !           195:        "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
        !           196:        "TLS_ECDHE_RSA_WITH_NULL_SHA",
        !           197:        "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
        !           198:        "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
        !           199:        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
        !           200:        "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
        !           201:        "TLS_ECDH_anon_WITH_NULL_SHA",
        !           202:        "TLS_ECDH_anon_WITH_RC4_128_SHA",
        !           203:        "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
        !           204:        "TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
        !           205:        "TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
        !           206:        "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA",
        !           207:        "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA",
        !           208:        "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA",
        !           209:        "TLS_SRP_SHA_WITH_AES_128_CBC_SHA",
        !           210:        "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA",
        !           211:        "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA",
        !           212:        "TLS_SRP_SHA_WITH_AES_256_CBC_SHA",
        !           213:        "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA",
        !           214:        "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA",
        !           215:        "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
        !           216:        "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
        !           217:        "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
        !           218:        "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
        !           219:        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
        !           220:        "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
        !           221:        "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
        !           222:        "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
        !           223:        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        !           224:        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        !           225:        "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
        !           226:        "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
        !           227:        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        !           228:        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        !           229:        "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
        !           230:        "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
        !           231:        "TLS_ECDHE_PSK_WITH_RC4_128_SHA",
        !           232:        "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA",
        !           233:        "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
        !           234:        "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
        !           235:        "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256",
        !           236:        "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384",
        !           237:        "TLS_ECDHE_PSK_WITH_NULL_SHA",
        !           238:        "TLS_ECDHE_PSK_WITH_NULL_SHA256",
        !           239:        "TLS_ECDHE_PSK_WITH_NULL_SHA384");
        !           240: ENUM_END(tls_cipher_suite_names, TLS_ECDHE_PSK_WITH_NULL_SHA384);
        !           241: 
        !           242: ENUM(tls_hash_algorithm_names, TLS_HASH_NONE, TLS_HASH_SHA512,
        !           243:        "NONE",
        !           244:        "MD5",
        !           245:        "SHA1",
        !           246:        "SHA224",
        !           247:        "SHA256",
        !           248:        "SHA384",
        !           249:        "SHA512",
        !           250: );
        !           251: 
        !           252: ENUM(tls_signature_algorithm_names, TLS_SIG_RSA, TLS_SIG_ECDSA,
        !           253:        "RSA",
        !           254:        "DSA",
        !           255:        "ECDSA",
        !           256: );
        !           257: 
        !           258: ENUM_BEGIN(tls_client_certificate_type_names,
        !           259:                   TLS_RSA_SIGN, TLS_DSS_EPHEMERAL_DH,
        !           260:        "RSA_SIGN",
        !           261:        "DSA_SIGN",
        !           262:        "RSA_FIXED_DH",
        !           263:        "DSS_FIXED_DH",
        !           264:        "RSA_EPHEMERAL_DH",
        !           265:        "DSS_EPHEMERAL_DH");
        !           266: ENUM_NEXT(tls_client_certificate_type_names,
        !           267:                  TLS_FORTEZZA_DMS, TLS_FORTEZZA_DMS, TLS_DSS_EPHEMERAL_DH,
        !           268:        "FORTEZZA_DMS");
        !           269: ENUM_NEXT(tls_client_certificate_type_names,
        !           270:                  TLS_ECDSA_SIGN, TLS_ECDSA_FIXED_ECDH, TLS_FORTEZZA_DMS,
        !           271:        "ECDSA_SIGN",
        !           272:        "RSA_FIXED_ECDH",
        !           273:        "ECDSA_FIXED_ECDH");
        !           274: ENUM_END(tls_client_certificate_type_names, TLS_ECDSA_FIXED_ECDH);
        !           275: 
        !           276: ENUM(tls_ecc_curve_type_names, TLS_ECC_EXPLICIT_PRIME, TLS_ECC_NAMED_CURVE,
        !           277:        "EXPLICIT_PRIME",
        !           278:        "EXPLICIT_CHAR2",
        !           279:        "NAMED_CURVE",
        !           280: );
        !           281: 
        !           282: ENUM(tls_named_curve_names, TLS_SECT163K1, TLS_SECP521R1,
        !           283:        "SECT163K1",
        !           284:        "SECT163R1",
        !           285:        "SECT163R2",
        !           286:        "SECT193R1",
        !           287:        "SECT193R2",
        !           288:        "SECT233K1",
        !           289:        "SECT233R1",
        !           290:        "SECT239K1",
        !           291:        "SECT283K1",
        !           292:        "SECT283R1",
        !           293:        "SECT409K1",
        !           294:        "SECT409R1",
        !           295:        "SECT571K1",
        !           296:        "SECT571R1",
        !           297:        "SECP160K1",
        !           298:        "SECP160R1",
        !           299:        "SECP160R2",
        !           300:        "SECP192K1",
        !           301:        "SECP192R1",
        !           302:        "SECP224K1",
        !           303:        "SECP224R1",
        !           304:        "SECP256K1",
        !           305:        "SECP256R1",
        !           306:        "SECP384R1",
        !           307:        "SECP521R1",
        !           308: );
        !           309: 
        !           310: ENUM(tls_ansi_point_format_names, TLS_ANSI_COMPRESSED, TLS_ANSI_HYBRID_Y,
        !           311:        "compressed",
        !           312:        "compressed y",
        !           313:        "uncompressed",
        !           314:        "uncompressed y",
        !           315:        "hybrid",
        !           316:        "hybrid y",
        !           317: );
        !           318: 
        !           319: ENUM(tls_ec_point_format_names,
        !           320:         TLS_EC_POINT_UNCOMPRESSED, TLS_EC_POINT_ANSIX962_COMPRESSED_CHAR2,
        !           321:        "uncompressed",
        !           322:        "ansiX962 compressed prime",
        !           323:        "ansiX962 compressed char2",
        !           324: );
        !           325: 
        !           326: typedef struct private_tls_crypto_t private_tls_crypto_t;
        !           327: 
        !           328: /**
        !           329:  * Private data of an tls_crypto_t object.
        !           330:  */
        !           331: struct private_tls_crypto_t {
        !           332: 
        !           333:        /**
        !           334:         * Public tls_crypto_t interface.
        !           335:         */
        !           336:        tls_crypto_t public;
        !           337: 
        !           338:        /**
        !           339:         * Protection layer
        !           340:         */
        !           341:        tls_protection_t *protection;
        !           342: 
        !           343:        /**
        !           344:         * List of supported/acceptable cipher suites
        !           345:         */
        !           346:        tls_cipher_suite_t *suites;
        !           347: 
        !           348:        /**
        !           349:         * Number of supported suites
        !           350:         */
        !           351:        int suite_count;
        !           352: 
        !           353:        /**
        !           354:         * Selected cipher suite
        !           355:         */
        !           356:        tls_cipher_suite_t suite;
        !           357: 
        !           358:        /**
        !           359:         * RSA supported?
        !           360:         */
        !           361:        bool rsa;
        !           362: 
        !           363:        /**
        !           364:         * ECDSA supported?
        !           365:         */
        !           366:        bool ecdsa;
        !           367: 
        !           368:        /**
        !           369:         * TLS context
        !           370:         */
        !           371:        tls_t *tls;
        !           372: 
        !           373:        /**
        !           374:         * TLS session cache
        !           375:         */
        !           376:        tls_cache_t *cache;
        !           377: 
        !           378:        /**
        !           379:         * All handshake data concatenated
        !           380:         */
        !           381:        chunk_t handshake;
        !           382: 
        !           383:        /**
        !           384:         * Connection state TLS PRF
        !           385:         */
        !           386:        tls_prf_t *prf;
        !           387: 
        !           388:        /**
        !           389:         * AEAD transform for inbound traffic
        !           390:         */
        !           391:        tls_aead_t *aead_in;
        !           392: 
        !           393:        /**
        !           394:         * AEAD transform for outbound traffic
        !           395:         */
        !           396:        tls_aead_t *aead_out;
        !           397: 
        !           398:        /**
        !           399:         * EAP-[T]TLS MSK
        !           400:         */
        !           401:        chunk_t msk;
        !           402: 
        !           403:        /**
        !           404:         * ASCII string constant used as seed for EAP-[T]TLS MSK PRF
        !           405:         */
        !           406:        char *msk_label;
        !           407: };
        !           408: 
        !           409: typedef struct {
        !           410:        tls_cipher_suite_t suite;
        !           411:        key_type_t key;
        !           412:        diffie_hellman_group_t dh;
        !           413:        hash_algorithm_t hash;
        !           414:        pseudo_random_function_t prf;
        !           415:        integrity_algorithm_t mac;
        !           416:        encryption_algorithm_t encr;
        !           417:        size_t encr_size;
        !           418: } suite_algs_t;
        !           419: 
        !           420: /**
        !           421:  * Mapping suites to a set of algorithms
        !           422:  */
        !           423: static suite_algs_t suite_algs[] = {
        !           424:        { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
        !           425:                KEY_ECDSA, ECP_256_BIT,
        !           426:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           427:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
        !           428:        },
        !           429:        { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
        !           430:                KEY_ECDSA, ECP_256_BIT,
        !           431:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           432:                AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
        !           433:        },
        !           434:        { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
        !           435:                KEY_ECDSA, ECP_384_BIT,
        !           436:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           437:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
        !           438:        },
        !           439:        { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
        !           440:                KEY_ECDSA, ECP_384_BIT,
        !           441:                HASH_SHA384, PRF_HMAC_SHA2_384,
        !           442:                AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32
        !           443:        },
        !           444:        { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        !           445:                KEY_ECDSA, ECP_256_BIT,
        !           446:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           447:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
        !           448:        },
        !           449:        { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        !           450:                KEY_ECDSA, ECP_384_BIT,
        !           451:                HASH_SHA384, PRF_HMAC_SHA2_384,
        !           452:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
        !           453:        },
        !           454:        { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
        !           455:                KEY_RSA, ECP_256_BIT,
        !           456:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           457:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
        !           458:        },
        !           459:        { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
        !           460:                KEY_RSA, ECP_256_BIT,
        !           461:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           462:                AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
        !           463:        },
        !           464:        { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
        !           465:                KEY_RSA, ECP_384_BIT,
        !           466:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           467:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
        !           468:        },
        !           469:        { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
        !           470:                KEY_RSA, ECP_384_BIT,
        !           471:                HASH_SHA384, PRF_HMAC_SHA2_384,
        !           472:                AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32
        !           473:        },
        !           474:        { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
        !           475:                KEY_RSA, ECP_256_BIT,
        !           476:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           477:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
        !           478:        },
        !           479:        { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        !           480:                KEY_RSA, ECP_384_BIT,
        !           481:                HASH_SHA384, PRF_HMAC_SHA2_384,
        !           482:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
        !           483:        },
        !           484:        { TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
        !           485:                KEY_RSA, MODP_2048_BIT,
        !           486:                HASH_SHA256,PRF_HMAC_SHA2_256,
        !           487:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
        !           488:        },
        !           489:        { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
        !           490:                KEY_RSA, MODP_3072_BIT,
        !           491:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           492:                AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
        !           493:        },
        !           494:        { TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
        !           495:                KEY_RSA, MODP_3072_BIT,
        !           496:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           497:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
        !           498:        },
        !           499:        { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
        !           500:                KEY_RSA, MODP_4096_BIT,
        !           501:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           502:                AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32
        !           503:        },
        !           504:        { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
        !           505:                KEY_RSA, MODP_3072_BIT,
        !           506:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           507:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
        !           508:        },
        !           509:        { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
        !           510:                KEY_RSA, MODP_4096_BIT,
        !           511:                HASH_SHA384, PRF_HMAC_SHA2_384,
        !           512:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
        !           513:        },
        !           514:        { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
        !           515:                KEY_RSA, MODP_2048_BIT,
        !           516:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           517:                AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16
        !           518:        },
        !           519:        { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
        !           520:                KEY_RSA, MODP_3072_BIT,
        !           521:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           522:                AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16
        !           523:        },
        !           524:        { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
        !           525:                KEY_RSA, MODP_3072_BIT,
        !           526:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           527:                AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32
        !           528:        },
        !           529:        { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
        !           530:                KEY_RSA, MODP_4096_BIT,
        !           531:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           532:                AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32
        !           533:        },
        !           534:        { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
        !           535:                KEY_RSA, MODP_2048_BIT,
        !           536:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           537:                AUTH_HMAC_SHA1_160, ENCR_3DES, 0
        !           538:        },
        !           539:        { TLS_RSA_WITH_AES_128_CBC_SHA,
        !           540:                KEY_RSA, MODP_NONE,
        !           541:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           542:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
        !           543:        },
        !           544:        { TLS_RSA_WITH_AES_128_CBC_SHA256,
        !           545:                KEY_RSA, MODP_NONE,
        !           546:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           547:                AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
        !           548:        },
        !           549:        { TLS_RSA_WITH_AES_256_CBC_SHA,
        !           550:                KEY_RSA, MODP_NONE,
        !           551:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           552:                AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
        !           553:        },
        !           554:        { TLS_RSA_WITH_AES_256_CBC_SHA256,
        !           555:                KEY_RSA, MODP_NONE,
        !           556:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           557:                AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32
        !           558:        },
        !           559:        { TLS_RSA_WITH_AES_128_GCM_SHA256,
        !           560:                KEY_RSA, MODP_NONE,
        !           561:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           562:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
        !           563:        },
        !           564:        { TLS_RSA_WITH_AES_256_GCM_SHA384,
        !           565:                KEY_RSA, MODP_NONE,
        !           566:                HASH_SHA384, PRF_HMAC_SHA2_384,
        !           567:                AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
        !           568:        },
        !           569:        { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
        !           570:                KEY_RSA, MODP_NONE,
        !           571:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           572:                AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16
        !           573:        },
        !           574:        { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
        !           575:                KEY_RSA, MODP_NONE,
        !           576:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           577:                AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16
        !           578:        },
        !           579:        { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
        !           580:                KEY_RSA, MODP_NONE,
        !           581:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           582:                AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32
        !           583:        },
        !           584:        { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
        !           585:                KEY_RSA, MODP_NONE,
        !           586:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           587:                AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32
        !           588:        },
        !           589:        { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
        !           590:                KEY_ECDSA, ECP_256_BIT,
        !           591:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           592:                AUTH_HMAC_SHA1_160, ENCR_3DES, 0
        !           593:        },
        !           594:        { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
        !           595:                KEY_RSA, ECP_256_BIT,
        !           596:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           597:                AUTH_HMAC_SHA1_160, ENCR_3DES, 0
        !           598:        },
        !           599:        { TLS_RSA_WITH_3DES_EDE_CBC_SHA,
        !           600:                KEY_RSA, MODP_NONE,
        !           601:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           602:                AUTH_HMAC_SHA1_160, ENCR_3DES, 0
        !           603:        },
        !           604:        { TLS_ECDHE_ECDSA_WITH_NULL_SHA,
        !           605:                KEY_ECDSA, ECP_256_BIT,
        !           606:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           607:                AUTH_HMAC_SHA1_160, ENCR_NULL, 0
        !           608:        },
        !           609:        { TLS_ECDHE_RSA_WITH_NULL_SHA,
        !           610:                KEY_ECDSA, ECP_256_BIT,
        !           611:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           612:                AUTH_HMAC_SHA1_160, ENCR_NULL, 0
        !           613:        },
        !           614:        { TLS_RSA_WITH_NULL_SHA,
        !           615:                KEY_RSA, MODP_NONE,
        !           616:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           617:                AUTH_HMAC_SHA1_160, ENCR_NULL, 0
        !           618:        },
        !           619:        { TLS_RSA_WITH_NULL_SHA256,
        !           620:                KEY_RSA, MODP_NONE,
        !           621:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           622:                AUTH_HMAC_SHA2_256_256, ENCR_NULL, 0
        !           623:        },
        !           624:        { TLS_RSA_WITH_NULL_MD5,
        !           625:                KEY_RSA, MODP_NONE,
        !           626:                HASH_SHA256, PRF_HMAC_SHA2_256,
        !           627:                AUTH_HMAC_MD5_128, ENCR_NULL, 0
        !           628:        },
        !           629: };
        !           630: 
        !           631: /**
        !           632:  * Look up algorithms by a suite
        !           633:  */
        !           634: static suite_algs_t *find_suite(tls_cipher_suite_t suite)
        !           635: {
        !           636:        int i;
        !           637: 
        !           638:        for (i = 0; i < countof(suite_algs); i++)
        !           639:        {
        !           640:                if (suite_algs[i].suite == suite)
        !           641:                {
        !           642:                        return &suite_algs[i];
        !           643:                }
        !           644:        }
        !           645:        return NULL;
        !           646: }
        !           647: 
        !           648: /**
        !           649:  * Filter a suite list using a transform enumerator
        !           650:  */
        !           651: static void filter_suite(suite_algs_t suites[], int *count, int offset,
        !           652:                                                 enumerator_t*(*create_enumerator)(crypto_factory_t*))
        !           653: {
        !           654:        const char *plugin_name;
        !           655:        suite_algs_t current;
        !           656:        int *current_alg, i, remaining = 0;
        !           657:        enumerator_t *enumerator;
        !           658: 
        !           659:        memset(&current, 0, sizeof(current));
        !           660:        current_alg = (int*)((char*)&current + offset);
        !           661: 
        !           662:        for (i = 0; i < *count; i++)
        !           663:        {
        !           664:                if (create_enumerator == lib->crypto->create_crypter_enumerator &&
        !           665:                        encryption_algorithm_is_aead(suites[i].encr))
        !           666:                {       /* filtering crypters, but current suite uses an AEAD, apply */
        !           667:                        suites[remaining] = suites[i];
        !           668:                        remaining++;
        !           669:                        continue;
        !           670:                }
        !           671:                if (create_enumerator == lib->crypto->create_aead_enumerator &&
        !           672:                        !encryption_algorithm_is_aead(suites[i].encr))
        !           673:                {       /* filtering AEADs, but current suite doesn't use one, apply */
        !           674:                        suites[remaining] = suites[i];
        !           675:                        remaining++;
        !           676:                        continue;
        !           677:                }
        !           678:                enumerator = create_enumerator(lib->crypto);
        !           679:                while (enumerator->enumerate(enumerator, current_alg, &plugin_name))
        !           680:                {
        !           681:                        if (current.encr && current.encr != suites[i].encr)
        !           682:                        {
        !           683:                                if (suites[i].encr != ENCR_NULL)
        !           684:                                {       /* skip, ENCR does not match nor is NULL */
        !           685:                                        continue;
        !           686:                                }
        !           687:                        }
        !           688:                        if (current.mac && current.mac != suites[i].mac)
        !           689:                        {
        !           690:                                if (suites[i].mac != AUTH_UNDEFINED)
        !           691:                                {       /* skip, MAC does not match nor is it undefined */
        !           692:                                        continue;
        !           693:                                }
        !           694:                        }
        !           695:                        if (current.prf && current.prf != suites[i].prf)
        !           696:                        {       /* skip, PRF does not match */
        !           697:                                continue;
        !           698:                        }
        !           699:                        if (current.hash && current.hash != suites[i].hash)
        !           700:                        {       /* skip, hash does not match */
        !           701:                                continue;
        !           702:                        }
        !           703:                        if (current.dh && current.dh != suites[i].dh)
        !           704:                        {
        !           705:                                if (suites[i].dh != MODP_NONE)
        !           706:                                {       /* skip DH group, does not match nor NONE */
        !           707:                                        continue;
        !           708:                                }
        !           709:                        }
        !           710:                        /* suite supported, apply */
        !           711:                        suites[remaining] = suites[i];
        !           712:                        remaining++;
        !           713:                        break;
        !           714:                }
        !           715:                enumerator->destroy(enumerator);
        !           716:        }
        !           717:        *count = remaining;
        !           718: }
        !           719: 
        !           720: /**
        !           721:  * Purge NULL encryption cipher suites from list
        !           722:  */
        !           723: static void filter_null_suites(suite_algs_t suites[], int *count)
        !           724: {
        !           725:        int i, remaining = 0;
        !           726: 
        !           727:        for (i = 0; i < *count; i++)
        !           728:        {
        !           729:                if (suites[i].encr != ENCR_NULL)
        !           730:                {
        !           731:                        suites[remaining] = suites[i];
        !           732:                        remaining++;
        !           733:                }
        !           734:        }
        !           735:        *count = remaining;
        !           736: }
        !           737: 
        !           738: /**
        !           739:  * Purge suites using a given key type
        !           740:  */
        !           741: static void filter_key_suites(private_tls_crypto_t *this,
        !           742:                                                          suite_algs_t suites[], int *count, key_type_t key)
        !           743: {
        !           744:        int i, remaining = 0;
        !           745: 
        !           746:        DBG2(DBG_TLS, "disabling %N suites, no backend found", key_type_names, key);
        !           747:        for (i = 0; i < *count; i++)
        !           748:        {
        !           749:                if (suites[i].key != key)
        !           750:                {
        !           751:                        suites[remaining] = suites[i];
        !           752:                        remaining++;
        !           753:                }
        !           754:        }
        !           755:        *count = remaining;
        !           756: }
        !           757: 
        !           758: /**
        !           759:  * Filter suites by key exchange user config
        !           760:  */
        !           761: static void filter_key_exchange_config_suites(private_tls_crypto_t *this,
        !           762:                                                                                          suite_algs_t suites[], int *count)
        !           763: {
        !           764:        enumerator_t *enumerator;
        !           765:        int i, remaining = 0;
        !           766:        char *token, *config;
        !           767: 
        !           768:        config = lib->settings->get_str(lib->settings, "%s.tls.key_exchange", NULL,
        !           769:                                                                        lib->ns);
        !           770:        if (config)
        !           771:        {
        !           772:                for (i = 0; i < *count; i++)
        !           773:                {
        !           774:                        enumerator = enumerator_create_token(config, ",", " ");
        !           775:                        while (enumerator->enumerate(enumerator, &token))
        !           776:                        {
        !           777:                                if (strcaseeq(token, "ecdhe-ecdsa") &&
        !           778:                                        diffie_hellman_group_is_ec(suites[i].dh) &&
        !           779:                                        suites[i].key == KEY_ECDSA)
        !           780:                                {
        !           781:                                        suites[remaining++] = suites[i];
        !           782:                                        break;
        !           783:                                }
        !           784:                                if (strcaseeq(token, "ecdhe-rsa") &&
        !           785:                                        diffie_hellman_group_is_ec(suites[i].dh) &&
        !           786:                                        suites[i].key == KEY_RSA)
        !           787:                                {
        !           788:                                        suites[remaining++] = suites[i];
        !           789:                                        break;
        !           790:                                }
        !           791:                                if (strcaseeq(token, "dhe-rsa") &&
        !           792:                                        !diffie_hellman_group_is_ec(suites[i].dh) &&
        !           793:                                        suites[i].dh != MODP_NONE &&
        !           794:                                        suites[i].key == KEY_RSA)
        !           795:                                {
        !           796:                                        suites[remaining++] = suites[i];
        !           797:                                        break;
        !           798:                                }
        !           799:                                if (strcaseeq(token, "rsa") &&
        !           800:                                        suites[i].dh == MODP_NONE &&
        !           801:                                        suites[i].key == KEY_RSA)
        !           802:                                {
        !           803:                                        suites[remaining++] = suites[i];
        !           804:                                        break;
        !           805:                                }
        !           806:                        }
        !           807:                        enumerator->destroy(enumerator);
        !           808:                }
        !           809:                *count = remaining;
        !           810:        }
        !           811: }
        !           812: 
        !           813: /**
        !           814:  * Filter suites by cipher user config
        !           815:  */
        !           816: static void filter_cipher_config_suites(private_tls_crypto_t *this,
        !           817:                                                                                suite_algs_t suites[], int *count)
        !           818: {
        !           819:        enumerator_t *enumerator;
        !           820:        int i, remaining = 0;
        !           821:        char *token, *config;
        !           822: 
        !           823:        config = lib->settings->get_str(lib->settings, "%s.tls.cipher", NULL,
        !           824:                                                                        lib->ns);
        !           825:        if (config)
        !           826:        {
        !           827:                for (i = 0; i < *count; i++)
        !           828:                {
        !           829:                        enumerator = enumerator_create_token(config, ",", " ");
        !           830:                        while (enumerator->enumerate(enumerator, &token))
        !           831:                        {
        !           832:                                if (strcaseeq(token, "aes128") &&
        !           833:                                        suites[i].encr == ENCR_AES_CBC &&
        !           834:                                        suites[i].encr_size == 16)
        !           835:                                {
        !           836:                                        suites[remaining++] = suites[i];
        !           837:                                        break;
        !           838:                                }
        !           839:                                if (strcaseeq(token, "aes256") &&
        !           840:                                        suites[i].encr == ENCR_AES_CBC &&
        !           841:                                        suites[i].encr_size == 32)
        !           842:                                {
        !           843:                                        suites[remaining++] = suites[i];
        !           844:                                        break;
        !           845:                                }
        !           846:                                if (strcaseeq(token, "aes128gcm") &&
        !           847:                                        suites[i].encr == ENCR_AES_GCM_ICV16 &&
        !           848:                                        suites[i].encr_size == 16)
        !           849:                                {
        !           850:                                        suites[remaining++] = suites[i];
        !           851:                                        break;
        !           852:                                }
        !           853:                                if (strcaseeq(token, "aes256gcm") &&
        !           854:                                        suites[i].encr == ENCR_AES_GCM_ICV16 &&
        !           855:                                        suites[i].encr_size == 32)
        !           856:                                {
        !           857:                                        suites[remaining++] = suites[i];
        !           858:                                        break;
        !           859:                                }
        !           860:                                if (strcaseeq(token, "camellia128") &&
        !           861:                                        suites[i].encr == ENCR_CAMELLIA_CBC &&
        !           862:                                        suites[i].encr_size == 16)
        !           863:                                {
        !           864:                                        suites[remaining++] = suites[i];
        !           865:                                        break;
        !           866:                                }
        !           867:                                if (strcaseeq(token, "camellia256") &&
        !           868:                                        suites[i].encr == ENCR_CAMELLIA_CBC &&
        !           869:                                        suites[i].encr_size == 32)
        !           870:                                {
        !           871:                                        suites[remaining++] = suites[i];
        !           872:                                        break;
        !           873:                                }
        !           874:                                if (strcaseeq(token, "3des") &&
        !           875:                                        suites[i].encr == ENCR_3DES)
        !           876:                                {
        !           877:                                        suites[remaining++] = suites[i];
        !           878:                                        break;
        !           879:                                }
        !           880:                                if (strcaseeq(token, "null") &&
        !           881:                                        suites[i].encr == ENCR_NULL)
        !           882:                                {
        !           883:                                        suites[remaining++] = suites[i];
        !           884:                                        break;
        !           885:                                }
        !           886:                        }
        !           887:                        enumerator->destroy(enumerator);
        !           888:                }
        !           889:                *count = remaining;
        !           890:        }
        !           891: }
        !           892: 
        !           893: /**
        !           894:  * Filter suites by mac user config
        !           895:  */
        !           896: static void filter_mac_config_suites(private_tls_crypto_t *this,
        !           897:                                                                         suite_algs_t suites[], int *count)
        !           898: {
        !           899:        enumerator_t *enumerator;
        !           900:        int i, remaining = 0;
        !           901:        char *token, *config;
        !           902: 
        !           903:        config = lib->settings->get_str(lib->settings, "%s.tls.mac", NULL,
        !           904:                                                                        lib->ns);
        !           905:        if (config)
        !           906:        {
        !           907:                for (i = 0; i < *count; i++)
        !           908:                {
        !           909:                        enumerator = enumerator_create_token(config, ",", " ");
        !           910:                        while (enumerator->enumerate(enumerator, &token))
        !           911:                        {
        !           912:                                if (strcaseeq(token, "md5") &&
        !           913:                                        suites[i].mac == AUTH_HMAC_MD5_128)
        !           914:                                {
        !           915:                                        suites[remaining++] = suites[i];
        !           916:                                        break;
        !           917:                                }
        !           918:                                if (strcaseeq(token, "sha1") &&
        !           919:                                        suites[i].mac == AUTH_HMAC_SHA1_160)
        !           920:                                {
        !           921:                                        suites[remaining++] = suites[i];
        !           922:                                        break;
        !           923:                                }
        !           924:                                if (strcaseeq(token, "sha256") &&
        !           925:                                        suites[i].mac == AUTH_HMAC_SHA2_256_256)
        !           926:                                {
        !           927:                                        suites[remaining++] = suites[i];
        !           928:                                        break;
        !           929:                                }
        !           930:                                if (strcaseeq(token, "sha384") &&
        !           931:                                        suites[i].mac == AUTH_HMAC_SHA2_384_384)
        !           932:                                {
        !           933:                                        suites[remaining++] = suites[i];
        !           934:                                        break;
        !           935:                                }
        !           936:                        }
        !           937:                        enumerator->destroy(enumerator);
        !           938:                }
        !           939:                *count = remaining;
        !           940:        }
        !           941: }
        !           942: 
        !           943: /**
        !           944:  * Filter for specific suites specified in strongswan.conf
        !           945:  */
        !           946: static void filter_specific_config_suites(private_tls_crypto_t *this,
        !           947:                                                                                  suite_algs_t suites[], int *count)
        !           948: {
        !           949:        enumerator_t *enumerator;
        !           950:        int i, remaining = 0, suite;
        !           951:        char *token, *config;
        !           952: 
        !           953:        config = lib->settings->get_str(lib->settings, "%s.tls.suites", NULL,
        !           954:                                                                        lib->ns);
        !           955:        if (config)
        !           956:        {
        !           957:                for (i = 0; i < *count; i++)
        !           958:                {
        !           959:                        enumerator = enumerator_create_token(config, ",", " ");
        !           960:                        while (enumerator->enumerate(enumerator, &token))
        !           961:                        {
        !           962:                                if (enum_from_name(tls_cipher_suite_names, token, &suite) &&
        !           963:                                        suite == suites[i].suite)
        !           964:                                {
        !           965:                                        suites[remaining++] = suites[i];
        !           966:                                        break;
        !           967:                                }
        !           968:                        }
        !           969:                        enumerator->destroy(enumerator);
        !           970:                }
        !           971:                *count = remaining;
        !           972:        }
        !           973: }
        !           974: 
        !           975: /**
        !           976:  * Filter out unsupported suites on given suite array
        !           977:  */
        !           978: static void filter_unsupported_suites(suite_algs_t suites[], int *count)
        !           979: {
        !           980:        /* filter suite list by each algorithm */
        !           981:        filter_suite(suites, count, offsetof(suite_algs_t, encr),
        !           982:                                 lib->crypto->create_crypter_enumerator);
        !           983:        filter_suite(suites, count, offsetof(suite_algs_t, encr),
        !           984:                                 lib->crypto->create_aead_enumerator);
        !           985:        filter_suite(suites, count, offsetof(suite_algs_t, mac),
        !           986:                                 lib->crypto->create_signer_enumerator);
        !           987:        filter_suite(suites, count, offsetof(suite_algs_t, prf),
        !           988:                                 lib->crypto->create_prf_enumerator);
        !           989:        filter_suite(suites, count, offsetof(suite_algs_t, hash),
        !           990:                                 lib->crypto->create_hasher_enumerator);
        !           991:        filter_suite(suites, count, offsetof(suite_algs_t, dh),
        !           992:                                 lib->crypto->create_dh_enumerator);
        !           993: }
        !           994: 
        !           995: /**
        !           996:  * Initialize the cipher suite list
        !           997:  */
        !           998: static void build_cipher_suite_list(private_tls_crypto_t *this,
        !           999:                                                                        bool require_encryption)
        !          1000: {
        !          1001:        suite_algs_t suites[countof(suite_algs)];
        !          1002:        int count = countof(suite_algs), i;
        !          1003: 
        !          1004:        /* copy all suites */
        !          1005:        for (i = 0; i < count; i++)
        !          1006:        {
        !          1007:                suites[i] = suite_algs[i];
        !          1008:        }
        !          1009: 
        !          1010:        if (require_encryption)
        !          1011:        {
        !          1012:                filter_null_suites(suites, &count);
        !          1013:        }
        !          1014:        if (!this->rsa)
        !          1015:        {
        !          1016:                filter_key_suites(this, suites, &count, KEY_RSA);
        !          1017:        }
        !          1018:        if (!this->ecdsa)
        !          1019:        {
        !          1020:                filter_key_suites(this, suites, &count, KEY_ECDSA);
        !          1021:        }
        !          1022: 
        !          1023:        filter_unsupported_suites(suites, &count);
        !          1024: 
        !          1025:        /* filter suites with strongswan.conf options */
        !          1026:        filter_key_exchange_config_suites(this, suites, &count);
        !          1027:        filter_cipher_config_suites(this, suites, &count);
        !          1028:        filter_mac_config_suites(this, suites, &count);
        !          1029:        filter_specific_config_suites(this, suites, &count);
        !          1030: 
        !          1031:        free(this->suites);
        !          1032:        this->suite_count = count;
        !          1033:        this->suites = malloc(sizeof(tls_cipher_suite_t) * count);
        !          1034: 
        !          1035:        DBG2(DBG_TLS, "%d supported TLS cipher suites:", count);
        !          1036:        for (i = 0; i < count; i++)
        !          1037:        {
        !          1038:                DBG2(DBG_TLS, "  %N", tls_cipher_suite_names, suites[i].suite);
        !          1039:                this->suites[i] = suites[i].suite;
        !          1040:        }
        !          1041: }
        !          1042: 
        !          1043: METHOD(tls_crypto_t, get_cipher_suites, int,
        !          1044:        private_tls_crypto_t *this, tls_cipher_suite_t **suites)
        !          1045: {
        !          1046:        *suites = this->suites;
        !          1047:        return this->suite_count;
        !          1048: }
        !          1049: 
        !          1050: /**
        !          1051:  * Create NULL encryption transforms
        !          1052:  */
        !          1053: static bool create_null(private_tls_crypto_t *this, suite_algs_t *algs)
        !          1054: {
        !          1055:        this->aead_in = tls_aead_create_null(algs->mac);
        !          1056:        this->aead_out = tls_aead_create_null(algs->mac);
        !          1057:        if (!this->aead_in || !this->aead_out)
        !          1058:        {
        !          1059:                DBG1(DBG_TLS, "selected TLS MAC %N not supported",
        !          1060:                         integrity_algorithm_names, algs->mac);
        !          1061:                return FALSE;
        !          1062:        }
        !          1063:        return TRUE;
        !          1064: }
        !          1065: 
        !          1066: /**
        !          1067:  * Create traditional transforms
        !          1068:  */
        !          1069: static bool create_traditional(private_tls_crypto_t *this, suite_algs_t *algs)
        !          1070: {
        !          1071:        if (this->tls->get_version(this->tls) < TLS_1_1)
        !          1072:        {
        !          1073:                this->aead_in = tls_aead_create_implicit(algs->mac,
        !          1074:                                                                algs->encr, algs->encr_size);
        !          1075:                this->aead_out = tls_aead_create_implicit(algs->mac,
        !          1076:                                                                algs->encr, algs->encr_size);
        !          1077:        }
        !          1078:        else
        !          1079:        {
        !          1080:                this->aead_in = tls_aead_create_explicit(algs->mac,
        !          1081:                                                                algs->encr, algs->encr_size);
        !          1082:                this->aead_out = tls_aead_create_explicit(algs->mac,
        !          1083:                                                                algs->encr, algs->encr_size);
        !          1084:        }
        !          1085:        if (!this->aead_in || !this->aead_out)
        !          1086:        {
        !          1087:                DBG1(DBG_TLS, "selected TLS transforms %N-%u-%N not supported",
        !          1088:                         encryption_algorithm_names, algs->encr, algs->encr_size * 8,
        !          1089:                         integrity_algorithm_names, algs->mac);
        !          1090:                return FALSE;
        !          1091:        }
        !          1092:        return TRUE;
        !          1093: }
        !          1094: 
        !          1095: /**
        !          1096:  * Create AEAD transforms
        !          1097:  */
        !          1098: static bool create_aead(private_tls_crypto_t *this, suite_algs_t *algs)
        !          1099: {
        !          1100:        this->aead_in = tls_aead_create_aead(algs->encr, algs->encr_size);
        !          1101:        this->aead_out = tls_aead_create_aead(algs->encr, algs->encr_size);
        !          1102:        if (!this->aead_in || !this->aead_out)
        !          1103:        {
        !          1104:                DBG1(DBG_TLS, "selected TLS transforms %N-%u not supported",
        !          1105:                         encryption_algorithm_names, algs->encr, algs->encr_size * 8);
        !          1106:                return FALSE;
        !          1107:        }
        !          1108:        return TRUE;
        !          1109: }
        !          1110: 
        !          1111: /**
        !          1112:  * Clean up and unset AEAD transforms
        !          1113:  */
        !          1114: static void destroy_aeads(private_tls_crypto_t *this)
        !          1115: {
        !          1116:        DESTROY_IF(this->aead_in);
        !          1117:        DESTROY_IF(this->aead_out);
        !          1118:        this->aead_in = this->aead_out = NULL;
        !          1119: }
        !          1120: 
        !          1121: /**
        !          1122:  * Create crypto primitives
        !          1123:  */
        !          1124: static bool create_ciphers(private_tls_crypto_t *this, suite_algs_t *algs)
        !          1125: {
        !          1126:        destroy_aeads(this);
        !          1127:        DESTROY_IF(this->prf);
        !          1128:        if (this->tls->get_version(this->tls) < TLS_1_2)
        !          1129:        {
        !          1130:                this->prf = tls_prf_create_10();
        !          1131:        }
        !          1132:        else
        !          1133:        {
        !          1134:                this->prf = tls_prf_create_12(algs->prf);
        !          1135:        }
        !          1136:        if (!this->prf)
        !          1137:        {
        !          1138:                DBG1(DBG_TLS, "selected TLS PRF not supported");
        !          1139:                return FALSE;
        !          1140:        }
        !          1141:        if (algs->encr == ENCR_NULL)
        !          1142:        {
        !          1143:                if (create_null(this, algs))
        !          1144:                {
        !          1145:                        return TRUE;
        !          1146:                }
        !          1147:        }
        !          1148:        else if (encryption_algorithm_is_aead(algs->encr))
        !          1149:        {
        !          1150:                if (create_aead(this, algs))
        !          1151:                {
        !          1152:                        return TRUE;
        !          1153:                }
        !          1154:        }
        !          1155:        else
        !          1156:        {
        !          1157:                if (create_traditional(this, algs))
        !          1158:                {
        !          1159:                        return TRUE;
        !          1160:                }
        !          1161:        }
        !          1162:        destroy_aeads(this);
        !          1163:        return FALSE;
        !          1164: }
        !          1165: 
        !          1166: METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
        !          1167:        private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count,
        !          1168:        key_type_t key)
        !          1169: {
        !          1170:        suite_algs_t *algs;
        !          1171:        int i, j;
        !          1172: 
        !          1173:        for (i = 0; i < this->suite_count; i++)
        !          1174:        {
        !          1175:                for (j = 0; j < count; j++)
        !          1176:                {
        !          1177:                        if (this->suites[i] == suites[j])
        !          1178:                        {
        !          1179:                                algs = find_suite(this->suites[i]);
        !          1180:                                if (algs)
        !          1181:                                {
        !          1182:                                        if (key == KEY_ANY || key == algs->key)
        !          1183:                                        {
        !          1184:                                                if (create_ciphers(this, algs))
        !          1185:                                                {
        !          1186:                                                        this->suite = this->suites[i];
        !          1187:                                                        return this->suite;
        !          1188:                                                }
        !          1189:                                        }
        !          1190:                                }
        !          1191:                        }
        !          1192:                }
        !          1193:        }
        !          1194:        return 0;
        !          1195: }
        !          1196: 
        !          1197: METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t,
        !          1198:        private_tls_crypto_t *this)
        !          1199: {
        !          1200:        suite_algs_t *algs;
        !          1201: 
        !          1202:        algs = find_suite(this->suite);
        !          1203:        if (algs)
        !          1204:        {
        !          1205:                return algs->dh;
        !          1206:        }
        !          1207:        return MODP_NONE;
        !          1208: }
        !          1209: 
        !          1210: /**
        !          1211:  * Map signature schemes to TLS key types and hashes, ordered by preference
        !          1212:  */
        !          1213: static struct {
        !          1214:        tls_signature_algorithm_t sig;
        !          1215:        tls_hash_algorithm_t hash;
        !          1216:        signature_scheme_t scheme;
        !          1217: } schemes[] = {
        !          1218:        { TLS_SIG_ECDSA,        TLS_HASH_SHA256,        SIGN_ECDSA_WITH_SHA256_DER   },
        !          1219:        { TLS_SIG_ECDSA,        TLS_HASH_SHA384,        SIGN_ECDSA_WITH_SHA384_DER   },
        !          1220:        { TLS_SIG_ECDSA,        TLS_HASH_SHA512,        SIGN_ECDSA_WITH_SHA512_DER   },
        !          1221:        { TLS_SIG_ECDSA,        TLS_HASH_SHA1,          SIGN_ECDSA_WITH_SHA1_DER     },
        !          1222:        { TLS_SIG_RSA,          TLS_HASH_SHA256,        SIGN_RSA_EMSA_PKCS1_SHA2_256 },
        !          1223:        { TLS_SIG_RSA,          TLS_HASH_SHA384,        SIGN_RSA_EMSA_PKCS1_SHA2_384 },
        !          1224:        { TLS_SIG_RSA,          TLS_HASH_SHA512,        SIGN_RSA_EMSA_PKCS1_SHA2_512 },
        !          1225:        { TLS_SIG_RSA,          TLS_HASH_SHA224,        SIGN_RSA_EMSA_PKCS1_SHA2_224 },
        !          1226:        { TLS_SIG_RSA,          TLS_HASH_SHA1,          SIGN_RSA_EMSA_PKCS1_SHA1     },
        !          1227:        { TLS_SIG_RSA,          TLS_HASH_MD5,           SIGN_RSA_EMSA_PKCS1_MD5      },
        !          1228: };
        !          1229: 
        !          1230: METHOD(tls_crypto_t, get_signature_algorithms, void,
        !          1231:        private_tls_crypto_t *this, bio_writer_t *writer)
        !          1232: {
        !          1233:        bio_writer_t *supported;
        !          1234:        int i;
        !          1235: 
        !          1236:        supported = bio_writer_create(32);
        !          1237: 
        !          1238:        for (i = 0; i < countof(schemes); i++)
        !          1239:        {
        !          1240:                if (schemes[i].sig == TLS_SIG_RSA && !this->rsa)
        !          1241:                {
        !          1242:                        continue;
        !          1243:                }
        !          1244:                if (schemes[i].sig == TLS_SIG_ECDSA && !this->ecdsa)
        !          1245:                {
        !          1246:                        continue;
        !          1247:                }
        !          1248:                if (!lib->plugins->has_feature(lib->plugins,
        !          1249:                                                PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].scheme)))
        !          1250:                {
        !          1251:                        continue;
        !          1252:                }
        !          1253:                supported->write_uint8(supported, schemes[i].hash);
        !          1254:                supported->write_uint8(supported, schemes[i].sig);
        !          1255:        }
        !          1256: 
        !          1257:        supported->wrap16(supported);
        !          1258:        writer->write_data16(writer, supported->get_buf(supported));
        !          1259:        supported->destroy(supported);
        !          1260: }
        !          1261: 
        !          1262: /**
        !          1263:  * Get the signature scheme from a TLS 1.2 hash/sig algorithm pair
        !          1264:  */
        !          1265: static signature_scheme_t hashsig_to_scheme(key_type_t type,
        !          1266:                                                                                        tls_hash_algorithm_t hash,
        !          1267:                                                                                        tls_signature_algorithm_t sig)
        !          1268: {
        !          1269:        int i;
        !          1270: 
        !          1271:        if ((sig == TLS_SIG_RSA && type == KEY_RSA) ||
        !          1272:                (sig == TLS_SIG_ECDSA && type == KEY_ECDSA))
        !          1273:        {
        !          1274:                for (i = 0; i < countof(schemes); i++)
        !          1275:                {
        !          1276:                        if (schemes[i].sig == sig && schemes[i].hash == hash)
        !          1277:                        {
        !          1278:                                return schemes[i].scheme;
        !          1279:                        }
        !          1280:                }
        !          1281:        }
        !          1282:        return SIGN_UNKNOWN;
        !          1283: }
        !          1284: 
        !          1285: /**
        !          1286:  * Mapping groups to TLS named curves
        !          1287:  */
        !          1288: static struct {
        !          1289:        diffie_hellman_group_t group;
        !          1290:        tls_named_curve_t curve;
        !          1291: } curves[] = {
        !          1292:        { ECP_256_BIT, TLS_SECP256R1},
        !          1293:        { ECP_384_BIT, TLS_SECP384R1},
        !          1294:        { ECP_521_BIT, TLS_SECP521R1},
        !          1295:        { ECP_224_BIT, TLS_SECP224R1},
        !          1296:        { ECP_192_BIT, TLS_SECP192R1},
        !          1297: };
        !          1298: 
        !          1299: CALLBACK(group_filter, bool,
        !          1300:        void *null, enumerator_t *orig, va_list args)
        !          1301: {
        !          1302:        diffie_hellman_group_t group, *out;
        !          1303:        tls_named_curve_t *curve;
        !          1304:        char *plugin;
        !          1305:        int i;
        !          1306: 
        !          1307:        VA_ARGS_VGET(args, out, curve);
        !          1308: 
        !          1309:        while (orig->enumerate(orig, &group, &plugin))
        !          1310:        {
        !          1311:                for (i = 0; i < countof(curves); i++)
        !          1312:                {
        !          1313:                        if (curves[i].group == group)
        !          1314:                        {
        !          1315:                                if (out)
        !          1316:                                {
        !          1317:                                        *out = curves[i].group;
        !          1318:                                }
        !          1319:                                if (curve)
        !          1320:                                {
        !          1321:                                        *curve = curves[i].curve;
        !          1322:                                }
        !          1323:                                return TRUE;
        !          1324:                        }
        !          1325:                }
        !          1326:        }
        !          1327:        return FALSE;
        !          1328: }
        !          1329: 
        !          1330: METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*,
        !          1331:        private_tls_crypto_t *this)
        !          1332: {
        !          1333:        return enumerator_create_filter(
        !          1334:                                                        lib->crypto->create_dh_enumerator(lib->crypto),
        !          1335:                                                        group_filter, NULL, NULL);
        !          1336: }
        !          1337: 
        !          1338: METHOD(tls_crypto_t, set_protection, void,
        !          1339:        private_tls_crypto_t *this, tls_protection_t *protection)
        !          1340: {
        !          1341:        this->protection = protection;
        !          1342: }
        !          1343: 
        !          1344: METHOD(tls_crypto_t, append_handshake, void,
        !          1345:        private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data)
        !          1346: {
        !          1347:        uint32_t header;
        !          1348: 
        !          1349:        /* reconstruct handshake header */
        !          1350:        header = htonl(data.len | (type << 24));
        !          1351:        this->handshake = chunk_cat("mcc", this->handshake,
        !          1352:                                                                chunk_from_thing(header), data);
        !          1353: }
        !          1354: 
        !          1355: /**
        !          1356:  * Create a hash using the suites HASH algorithm
        !          1357:  */
        !          1358: static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash)
        !          1359: {
        !          1360:        if (this->tls->get_version(this->tls) >= TLS_1_2)
        !          1361:        {
        !          1362:                hasher_t *hasher;
        !          1363:                suite_algs_t *alg;
        !          1364: 
        !          1365:                alg = find_suite(this->suite);
        !          1366:                if (!alg)
        !          1367:                {
        !          1368:                        return FALSE;
        !          1369:                }
        !          1370:                hasher = lib->crypto->create_hasher(lib->crypto, alg->hash);
        !          1371:                if (!hasher || !hasher->allocate_hash(hasher, data, hash))
        !          1372:                {
        !          1373:                        DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash);
        !          1374:                        DESTROY_IF(hasher);
        !          1375:                        return FALSE;
        !          1376:                }
        !          1377:                hasher->destroy(hasher);
        !          1378:        }
        !          1379:        else
        !          1380:        {
        !          1381:                hasher_t *md5, *sha1;
        !          1382:                char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
        !          1383: 
        !          1384:                md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
        !          1385:                if (!md5 || !md5->get_hash(md5, data, buf))
        !          1386:                {
        !          1387:                        DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5);
        !          1388:                        DESTROY_IF(md5);
        !          1389:                        return FALSE;
        !          1390:                }
        !          1391:                md5->destroy(md5);
        !          1392:                sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
        !          1393:                if (!sha1 || !sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5))
        !          1394:                {
        !          1395:                        DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1);
        !          1396:                        DESTROY_IF(sha1);
        !          1397:                        return FALSE;
        !          1398:                }
        !          1399:                sha1->destroy(sha1);
        !          1400: 
        !          1401:                *hash = chunk_clone(chunk_from_thing(buf));
        !          1402:        }
        !          1403:        return TRUE;
        !          1404: }
        !          1405: 
        !          1406: METHOD(tls_crypto_t, sign, bool,
        !          1407:        private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
        !          1408:        chunk_t data, chunk_t hashsig)
        !          1409: {
        !          1410:        if (this->tls->get_version(this->tls) >= TLS_1_2)
        !          1411:        {
        !          1412:                const chunk_t hashsig_def = chunk_from_chars(
        !          1413:                                        TLS_HASH_SHA1, TLS_SIG_RSA, TLS_HASH_SHA1, TLS_SIG_ECDSA);
        !          1414:                signature_scheme_t scheme;
        !          1415:                bio_reader_t *reader;
        !          1416:                uint8_t hash, alg;
        !          1417:                chunk_t sig;
        !          1418:                bool done = FALSE;
        !          1419: 
        !          1420:                if (!hashsig.len)
        !          1421:                {       /* fallback if none given */
        !          1422:                        hashsig = hashsig_def;
        !          1423:                }
        !          1424:                reader = bio_reader_create(hashsig);
        !          1425:                while (reader->remaining(reader) >= 2)
        !          1426:                {
        !          1427:                        if (reader->read_uint8(reader, &hash) &&
        !          1428:                                reader->read_uint8(reader, &alg))
        !          1429:                        {
        !          1430:                                scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
        !          1431:                                if (scheme != SIGN_UNKNOWN &&
        !          1432:                                        key->sign(key, scheme, NULL, data, &sig))
        !          1433:                                {
        !          1434:                                        done = TRUE;
        !          1435:                                        break;
        !          1436:                                }
        !          1437:                        }
        !          1438:                }
        !          1439:                reader->destroy(reader);
        !          1440:                if (!done)
        !          1441:                {
        !          1442:                        DBG1(DBG_TLS, "none of the proposed hash/sig algorithms supported");
        !          1443:                        return FALSE;
        !          1444:                }
        !          1445:                DBG2(DBG_TLS, "created signature with %N/%N",
        !          1446:                         tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
        !          1447:                writer->write_uint8(writer, hash);
        !          1448:                writer->write_uint8(writer, alg);
        !          1449:                writer->write_data16(writer, sig);
        !          1450:                free(sig.ptr);
        !          1451:        }
        !          1452:        else
        !          1453:        {
        !          1454:                chunk_t sig, hash;
        !          1455:                bool done;
        !          1456: 
        !          1457:                switch (key->get_type(key))
        !          1458:                {
        !          1459:                        case KEY_RSA:
        !          1460:                                if (!hash_data(this, data, &hash))
        !          1461:                                {
        !          1462:                                        return FALSE;
        !          1463:                                }
        !          1464:                                done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
        !          1465:                                                                 &sig);
        !          1466:                                free(hash.ptr);
        !          1467:                                if (!done)
        !          1468:                                {
        !          1469:                                        return FALSE;
        !          1470:                                }
        !          1471:                                DBG2(DBG_TLS, "created signature with MD5+SHA1/RSA");
        !          1472:                                break;
        !          1473:                        case KEY_ECDSA:
        !          1474:                                if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data, &sig))
        !          1475:                                {
        !          1476:                                        return FALSE;
        !          1477:                                }
        !          1478:                                DBG2(DBG_TLS, "created signature with SHA1/ECDSA");
        !          1479:                                break;
        !          1480:                        default:
        !          1481:                                return FALSE;
        !          1482:                }
        !          1483:                writer->write_data16(writer, sig);
        !          1484:                free(sig.ptr);
        !          1485:        }
        !          1486:        return TRUE;
        !          1487: }
        !          1488: 
        !          1489: METHOD(tls_crypto_t, verify, bool,
        !          1490:        private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader,
        !          1491:        chunk_t data)
        !          1492: {
        !          1493:        if (this->tls->get_version(this->tls) >= TLS_1_2)
        !          1494:        {
        !          1495:                signature_scheme_t scheme = SIGN_UNKNOWN;
        !          1496:                uint8_t hash, alg;
        !          1497:                chunk_t sig;
        !          1498: 
        !          1499:                if (!reader->read_uint8(reader, &hash) ||
        !          1500:                        !reader->read_uint8(reader, &alg) ||
        !          1501:                        !reader->read_data16(reader, &sig))
        !          1502:                {
        !          1503:                        DBG1(DBG_TLS, "received invalid signature");
        !          1504:                        return FALSE;
        !          1505:                }
        !          1506:                scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
        !          1507:                if (scheme == SIGN_UNKNOWN)
        !          1508:                {
        !          1509:                        DBG1(DBG_TLS, "signature algorithms %N/%N not supported",
        !          1510:                                 tls_hash_algorithm_names, hash,
        !          1511:                                 tls_signature_algorithm_names, alg);
        !          1512:                        return FALSE;
        !          1513:                }
        !          1514:                if (!key->verify(key, scheme, NULL, data, sig))
        !          1515:                {
        !          1516:                        return FALSE;
        !          1517:                }
        !          1518:                DBG2(DBG_TLS, "verified signature with %N/%N",
        !          1519:                         tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
        !          1520:        }
        !          1521:        else
        !          1522:        {
        !          1523:                chunk_t sig, hash;
        !          1524:                bool done;
        !          1525: 
        !          1526:                if (!reader->read_data16(reader, &sig))
        !          1527:                {
        !          1528:                        DBG1(DBG_TLS, "received invalid signature");
        !          1529:                        return FALSE;
        !          1530:                }
        !          1531:                switch (key->get_type(key))
        !          1532:                {
        !          1533:                        case KEY_RSA:
        !          1534:                                if (!hash_data(this, data, &hash))
        !          1535:                                {
        !          1536:                                        return FALSE;
        !          1537:                                }
        !          1538:                                done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
        !          1539:                                                                   sig);
        !          1540:                                free(hash.ptr);
        !          1541:                                if (!done)
        !          1542:                                {
        !          1543:                                        return FALSE;
        !          1544:                                }
        !          1545:                                DBG2(DBG_TLS, "verified signature data with MD5+SHA1/RSA");
        !          1546:                                break;
        !          1547:                        case KEY_ECDSA:
        !          1548:                                if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data,
        !          1549:                                                                 sig))
        !          1550:                                {
        !          1551:                                        return FALSE;
        !          1552:                                }
        !          1553:                                DBG2(DBG_TLS, "verified signature with SHA1/ECDSA");
        !          1554:                                break;
        !          1555:                        default:
        !          1556:                                return FALSE;
        !          1557:                }
        !          1558:        }
        !          1559:        return TRUE;
        !          1560: }
        !          1561: 
        !          1562: METHOD(tls_crypto_t, sign_handshake, bool,
        !          1563:        private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
        !          1564:        chunk_t hashsig)
        !          1565: {
        !          1566:        return sign(this, key, writer, this->handshake, hashsig);
        !          1567: }
        !          1568: 
        !          1569: METHOD(tls_crypto_t, verify_handshake, bool,
        !          1570:        private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader)
        !          1571: {
        !          1572:        return verify(this, key, reader, this->handshake);
        !          1573: }
        !          1574: 
        !          1575: METHOD(tls_crypto_t, calculate_finished, bool,
        !          1576:        private_tls_crypto_t *this, char *label, char out[12])
        !          1577: {
        !          1578:        chunk_t seed;
        !          1579: 
        !          1580:        if (!this->prf)
        !          1581:        {
        !          1582:                return FALSE;
        !          1583:        }
        !          1584:        if (!hash_data(this, this->handshake, &seed))
        !          1585:        {
        !          1586:                return FALSE;
        !          1587:        }
        !          1588:        if (!this->prf->get_bytes(this->prf, label, seed, 12, out))
        !          1589:        {
        !          1590:                free(seed.ptr);
        !          1591:                return FALSE;
        !          1592:        }
        !          1593:        free(seed.ptr);
        !          1594:        return TRUE;
        !          1595: }
        !          1596: 
        !          1597: /**
        !          1598:  * Derive master secret from premaster, optionally save session
        !          1599:  */
        !          1600: static bool derive_master(private_tls_crypto_t *this, chunk_t premaster,
        !          1601:                                                  chunk_t session, identification_t *id,
        !          1602:                                                  chunk_t client_random, chunk_t server_random)
        !          1603: {
        !          1604:        char master[48];
        !          1605:        chunk_t seed;
        !          1606: 
        !          1607:        /* derive master secret */
        !          1608:        seed = chunk_cata("cc", client_random, server_random);
        !          1609: 
        !          1610:        if (!this->prf->set_key(this->prf, premaster) ||
        !          1611:                !this->prf->get_bytes(this->prf, "master secret", seed,
        !          1612:                                                          sizeof(master), master) ||
        !          1613:                !this->prf->set_key(this->prf, chunk_from_thing(master)))
        !          1614:        {
        !          1615:                return FALSE;
        !          1616:        }
        !          1617: 
        !          1618:        if (this->cache && session.len)
        !          1619:        {
        !          1620:                this->cache->create(this->cache, session, id, chunk_from_thing(master),
        !          1621:                                                        this->suite);
        !          1622:        }
        !          1623:        memwipe(master, sizeof(master));
        !          1624:        return TRUE;
        !          1625: }
        !          1626: 
        !          1627: /**
        !          1628:  * Expand key material from master secret
        !          1629:  */
        !          1630: static bool expand_keys(private_tls_crypto_t *this,
        !          1631:                                                chunk_t client_random, chunk_t server_random)
        !          1632: {
        !          1633:        chunk_t seed, block;
        !          1634:        chunk_t cw_mac, cw, cw_iv;
        !          1635:        chunk_t sw_mac, sw, sw_iv;
        !          1636:        int mklen, eklen, ivlen;
        !          1637: 
        !          1638:        if (!this->aead_in || !this->aead_out)
        !          1639:        {
        !          1640:                return FALSE;
        !          1641:        }
        !          1642: 
        !          1643:        /* derive key block for key expansion */
        !          1644:        mklen = this->aead_in->get_mac_key_size(this->aead_in);
        !          1645:        eklen = this->aead_in->get_encr_key_size(this->aead_in);
        !          1646:        ivlen = this->aead_in->get_iv_size(this->aead_in);
        !          1647:        seed = chunk_cata("cc", server_random, client_random);
        !          1648:        block = chunk_alloca((mklen + eklen + ivlen) * 2);
        !          1649:        if (!this->prf->get_bytes(this->prf, "key expansion", seed,
        !          1650:                                                          block.len, block.ptr))
        !          1651:        {
        !          1652:                return FALSE;
        !          1653:        }
        !          1654: 
        !          1655:        /* client/server write signer keys */
        !          1656:        cw_mac = chunk_create(block.ptr, mklen);
        !          1657:        block = chunk_skip(block, mklen);
        !          1658:        sw_mac = chunk_create(block.ptr, mklen);
        !          1659:        block = chunk_skip(block, mklen);
        !          1660: 
        !          1661:        /* client/server write encryption keys */
        !          1662:        cw = chunk_create(block.ptr, eklen);
        !          1663:        block = chunk_skip(block, eklen);
        !          1664:        sw = chunk_create(block.ptr, eklen);
        !          1665:        block = chunk_skip(block, eklen);
        !          1666: 
        !          1667:        /* client/server write IV; TLS 1.0 implicit IVs or AEAD salt, if any */
        !          1668:        cw_iv = chunk_create(block.ptr, ivlen);
        !          1669:        block = chunk_skip(block, ivlen);
        !          1670:        sw_iv = chunk_create(block.ptr, ivlen);
        !          1671:        block = chunk_skip(block, ivlen);
        !          1672: 
        !          1673:        if (this->tls->is_server(this->tls))
        !          1674:        {
        !          1675:                if (!this->aead_in->set_keys(this->aead_in, cw_mac, cw, cw_iv) ||
        !          1676:                        !this->aead_out->set_keys(this->aead_out, sw_mac, sw, sw_iv))
        !          1677:                {
        !          1678:                        return FALSE;
        !          1679:                }
        !          1680:        }
        !          1681:        else
        !          1682:        {
        !          1683:                if (!this->aead_out->set_keys(this->aead_out, cw_mac, cw, cw_iv) ||
        !          1684:                        !this->aead_in->set_keys(this->aead_in, sw_mac, sw, sw_iv))
        !          1685:                {
        !          1686:                        return FALSE;
        !          1687:                }
        !          1688:        }
        !          1689: 
        !          1690:        /* EAP-MSK */
        !          1691:        if (this->msk_label)
        !          1692:        {
        !          1693:                seed = chunk_cata("cc", client_random, server_random);
        !          1694:                this->msk = chunk_alloc(64);
        !          1695:                if (!this->prf->get_bytes(this->prf, this->msk_label, seed,
        !          1696:                                                                  this->msk.len, this->msk.ptr))
        !          1697:                {
        !          1698:                        return FALSE;
        !          1699:                }
        !          1700:        }
        !          1701:        return TRUE;
        !          1702: }
        !          1703: 
        !          1704: METHOD(tls_crypto_t, derive_secrets, bool,
        !          1705:        private_tls_crypto_t *this, chunk_t premaster, chunk_t session,
        !          1706:        identification_t *id, chunk_t client_random, chunk_t server_random)
        !          1707: {
        !          1708:        return derive_master(this, premaster, session, id,
        !          1709:                                                 client_random, server_random) &&
        !          1710:                   expand_keys(this, client_random, server_random);
        !          1711: }
        !          1712: 
        !          1713: METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
        !          1714:        private_tls_crypto_t *this, chunk_t session, identification_t *id,
        !          1715:        chunk_t client_random, chunk_t server_random)
        !          1716: {
        !          1717:        chunk_t master;
        !          1718: 
        !          1719:        if (this->cache && session.len)
        !          1720:        {
        !          1721:                this->suite = this->cache->lookup(this->cache, session, id, &master);
        !          1722:                if (this->suite)
        !          1723:                {
        !          1724:                        this->suite = select_cipher_suite(this, &this->suite, 1, KEY_ANY);
        !          1725:                        if (this->suite)
        !          1726:                        {
        !          1727:                                if (!this->prf->set_key(this->prf, master) ||
        !          1728:                                        !expand_keys(this, client_random, server_random))
        !          1729:                                {
        !          1730:                                        this->suite = 0;
        !          1731:                                }
        !          1732:                        }
        !          1733:                        chunk_clear(&master);
        !          1734:                }
        !          1735:                return this->suite;
        !          1736:        }
        !          1737:        return 0;
        !          1738: }
        !          1739: 
        !          1740: METHOD(tls_crypto_t, get_session, chunk_t,
        !          1741:        private_tls_crypto_t *this, identification_t *server)
        !          1742: {
        !          1743:        if (this->cache)
        !          1744:        {
        !          1745:                return this->cache->check(this->cache, server);
        !          1746:        }
        !          1747:        return chunk_empty;
        !          1748: }
        !          1749: 
        !          1750: METHOD(tls_crypto_t, change_cipher, void,
        !          1751:        private_tls_crypto_t *this, bool inbound)
        !          1752: {
        !          1753:        if (this->protection)
        !          1754:        {
        !          1755:                if (inbound)
        !          1756:                {
        !          1757:                        this->protection->set_cipher(this->protection, TRUE, this->aead_in);
        !          1758:                }
        !          1759:                else
        !          1760:                {
        !          1761:                        this->protection->set_cipher(this->protection, FALSE, this->aead_out);
        !          1762:                }
        !          1763:        }
        !          1764: }
        !          1765: 
        !          1766: METHOD(tls_crypto_t, get_eap_msk, chunk_t,
        !          1767:        private_tls_crypto_t *this)
        !          1768: {
        !          1769:        return this->msk;
        !          1770: }
        !          1771: 
        !          1772: METHOD(tls_crypto_t, destroy, void,
        !          1773:        private_tls_crypto_t *this)
        !          1774: {
        !          1775:        destroy_aeads(this);
        !          1776:        free(this->handshake.ptr);
        !          1777:        free(this->msk.ptr);
        !          1778:        DESTROY_IF(this->prf);
        !          1779:        free(this->suites);
        !          1780:        free(this);
        !          1781: }
        !          1782: 
        !          1783: /**
        !          1784:  * See header
        !          1785:  */
        !          1786: tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache)
        !          1787: {
        !          1788:        private_tls_crypto_t *this;
        !          1789:        enumerator_t *enumerator;
        !          1790:        credential_type_t type;
        !          1791:        int subtype;
        !          1792: 
        !          1793:        INIT(this,
        !          1794:                .public = {
        !          1795:                        .get_cipher_suites = _get_cipher_suites,
        !          1796:                        .select_cipher_suite = _select_cipher_suite,
        !          1797:                        .get_dh_group = _get_dh_group,
        !          1798:                        .get_signature_algorithms = _get_signature_algorithms,
        !          1799:                        .create_ec_enumerator = _create_ec_enumerator,
        !          1800:                        .set_protection = _set_protection,
        !          1801:                        .append_handshake = _append_handshake,
        !          1802:                        .sign = _sign,
        !          1803:                        .verify = _verify,
        !          1804:                        .sign_handshake = _sign_handshake,
        !          1805:                        .verify_handshake = _verify_handshake,
        !          1806:                        .calculate_finished = _calculate_finished,
        !          1807:                        .derive_secrets = _derive_secrets,
        !          1808:                        .resume_session = _resume_session,
        !          1809:                        .get_session = _get_session,
        !          1810:                        .change_cipher = _change_cipher,
        !          1811:                        .get_eap_msk = _get_eap_msk,
        !          1812:                        .destroy = _destroy,
        !          1813:                },
        !          1814:                .tls = tls,
        !          1815:                .cache = cache,
        !          1816:        );
        !          1817: 
        !          1818:        enumerator = lib->creds->create_builder_enumerator(lib->creds);
        !          1819:        while (enumerator->enumerate(enumerator, &type, &subtype))
        !          1820:        {
        !          1821:                if (type == CRED_PUBLIC_KEY)
        !          1822:                {
        !          1823:                        switch (subtype)
        !          1824:                        {
        !          1825:                                case KEY_RSA:
        !          1826:                                        this->rsa = TRUE;
        !          1827:                                        break;
        !          1828:                                case KEY_ECDSA:
        !          1829:                                        this->ecdsa = TRUE;
        !          1830:                                        break;
        !          1831:                                default:
        !          1832:                                        break;
        !          1833:                        }
        !          1834:                }
        !          1835:        }
        !          1836:        enumerator->destroy(enumerator);
        !          1837: 
        !          1838:        switch (tls->get_purpose(tls))
        !          1839:        {
        !          1840:                case TLS_PURPOSE_EAP_TLS:
        !          1841:                        /* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
        !          1842:                        this->msk_label = "client EAP encryption";
        !          1843:                        build_cipher_suite_list(this, FALSE);
        !          1844:                        break;
        !          1845:                case TLS_PURPOSE_EAP_PEAP:
        !          1846:                        this->msk_label = "client EAP encryption";
        !          1847:                        build_cipher_suite_list(this, TRUE);
        !          1848:                        break;
        !          1849:                case TLS_PURPOSE_EAP_TTLS:
        !          1850:                        /* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
        !          1851:                        this->msk_label = "ttls keying material";
        !          1852:                        build_cipher_suite_list(this, TRUE);
        !          1853:                        break;
        !          1854:                case TLS_PURPOSE_GENERIC:
        !          1855:                        build_cipher_suite_list(this, TRUE);
        !          1856:                        break;
        !          1857:                case TLS_PURPOSE_GENERIC_NULLOK:
        !          1858:                        build_cipher_suite_list(this, FALSE);
        !          1859:                        break;
        !          1860:                default:
        !          1861:                        break;
        !          1862:        }
        !          1863:        return &this->public;
        !          1864: }
        !          1865: 
        !          1866: /**
        !          1867:  * See header.
        !          1868:  */
        !          1869: int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **out)
        !          1870: {
        !          1871:        suite_algs_t suites[countof(suite_algs)];
        !          1872:        int count = countof(suite_algs), i;
        !          1873: 
        !          1874:        /* initialize copy of suite list */
        !          1875:        for (i = 0; i < count; i++)
        !          1876:        {
        !          1877:                suites[i] = suite_algs[i];
        !          1878:        }
        !          1879: 
        !          1880:        filter_unsupported_suites(suites, &count);
        !          1881: 
        !          1882:        if (!null)
        !          1883:        {
        !          1884:                filter_null_suites(suites, &count);
        !          1885:        }
        !          1886: 
        !          1887:        if (out)
        !          1888:        {
        !          1889:                *out = calloc(count, sizeof(tls_cipher_suite_t));
        !          1890:                for (i = 0; i < count; i++)
        !          1891:                {
        !          1892:                        (*out)[i] = suites[i].suite;
        !          1893:                }
        !          1894:        }
        !          1895:        return count;
        !          1896: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>