1*62c56f98SSadaf Ebrahimi#!/usr/bin/env python3 2*62c56f98SSadaf Ebrahimi 3*62c56f98SSadaf Ebrahimi# translate_ciphers.py 4*62c56f98SSadaf Ebrahimi# 5*62c56f98SSadaf Ebrahimi# Copyright The Mbed TLS Contributors 6*62c56f98SSadaf Ebrahimi# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7*62c56f98SSadaf Ebrahimi 8*62c56f98SSadaf Ebrahimi""" 9*62c56f98SSadaf EbrahimiTranslate standard ciphersuite names to GnuTLS, OpenSSL and Mbed TLS standards. 10*62c56f98SSadaf Ebrahimi 11*62c56f98SSadaf EbrahimiTo test the translation functions run: 12*62c56f98SSadaf Ebrahimipython3 -m unittest translate_cipher.py 13*62c56f98SSadaf Ebrahimi""" 14*62c56f98SSadaf Ebrahimi 15*62c56f98SSadaf Ebrahimiimport re 16*62c56f98SSadaf Ebrahimiimport argparse 17*62c56f98SSadaf Ebrahimiimport unittest 18*62c56f98SSadaf Ebrahimi 19*62c56f98SSadaf Ebrahimiclass TestTranslateCiphers(unittest.TestCase): 20*62c56f98SSadaf Ebrahimi """ 21*62c56f98SSadaf Ebrahimi Ensure translate_ciphers.py translates and formats ciphersuite names 22*62c56f98SSadaf Ebrahimi correctly 23*62c56f98SSadaf Ebrahimi """ 24*62c56f98SSadaf Ebrahimi def test_translate_all_cipher_names(self): 25*62c56f98SSadaf Ebrahimi """ 26*62c56f98SSadaf Ebrahimi Translate standard ciphersuite names to GnuTLS, OpenSSL and 27*62c56f98SSadaf Ebrahimi Mbed TLS counterpart. Use only a small subset of ciphers 28*62c56f98SSadaf Ebrahimi that exercise each step of the translation functions 29*62c56f98SSadaf Ebrahimi """ 30*62c56f98SSadaf Ebrahimi ciphers = [ 31*62c56f98SSadaf Ebrahimi ("TLS_ECDHE_ECDSA_WITH_NULL_SHA", 32*62c56f98SSadaf Ebrahimi "+ECDHE-ECDSA:+NULL:+SHA1", 33*62c56f98SSadaf Ebrahimi "ECDHE-ECDSA-NULL-SHA", 34*62c56f98SSadaf Ebrahimi "TLS-ECDHE-ECDSA-WITH-NULL-SHA"), 35*62c56f98SSadaf Ebrahimi ("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 36*62c56f98SSadaf Ebrahimi "+ECDHE-ECDSA:+AES-128-GCM:+AEAD", 37*62c56f98SSadaf Ebrahimi "ECDHE-ECDSA-AES128-GCM-SHA256", 38*62c56f98SSadaf Ebrahimi "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"), 39*62c56f98SSadaf Ebrahimi ("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", 40*62c56f98SSadaf Ebrahimi "+DHE-RSA:+3DES-CBC:+SHA1", 41*62c56f98SSadaf Ebrahimi "EDH-RSA-DES-CBC3-SHA", 42*62c56f98SSadaf Ebrahimi "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA"), 43*62c56f98SSadaf Ebrahimi ("TLS_RSA_WITH_AES_256_CBC_SHA", 44*62c56f98SSadaf Ebrahimi "+RSA:+AES-256-CBC:+SHA1", 45*62c56f98SSadaf Ebrahimi "AES256-SHA", 46*62c56f98SSadaf Ebrahimi "TLS-RSA-WITH-AES-256-CBC-SHA"), 47*62c56f98SSadaf Ebrahimi ("TLS_PSK_WITH_3DES_EDE_CBC_SHA", 48*62c56f98SSadaf Ebrahimi "+PSK:+3DES-CBC:+SHA1", 49*62c56f98SSadaf Ebrahimi "PSK-3DES-EDE-CBC-SHA", 50*62c56f98SSadaf Ebrahimi "TLS-PSK-WITH-3DES-EDE-CBC-SHA"), 51*62c56f98SSadaf Ebrahimi ("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", 52*62c56f98SSadaf Ebrahimi None, 53*62c56f98SSadaf Ebrahimi "ECDHE-ECDSA-CHACHA20-POLY1305", 54*62c56f98SSadaf Ebrahimi "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256"), 55*62c56f98SSadaf Ebrahimi ("TLS_ECDHE_ECDSA_WITH_AES_128_CCM", 56*62c56f98SSadaf Ebrahimi "+ECDHE-ECDSA:+AES-128-CCM:+AEAD", 57*62c56f98SSadaf Ebrahimi None, 58*62c56f98SSadaf Ebrahimi "TLS-ECDHE-ECDSA-WITH-AES-128-CCM"), 59*62c56f98SSadaf Ebrahimi ("TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", 60*62c56f98SSadaf Ebrahimi None, 61*62c56f98SSadaf Ebrahimi "ECDHE-ARIA256-GCM-SHA384", 62*62c56f98SSadaf Ebrahimi "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384"), 63*62c56f98SSadaf Ebrahimi ] 64*62c56f98SSadaf Ebrahimi 65*62c56f98SSadaf Ebrahimi for s, g_exp, o_exp, m_exp in ciphers: 66*62c56f98SSadaf Ebrahimi 67*62c56f98SSadaf Ebrahimi if g_exp is not None: 68*62c56f98SSadaf Ebrahimi g = translate_gnutls(s) 69*62c56f98SSadaf Ebrahimi self.assertEqual(g, g_exp) 70*62c56f98SSadaf Ebrahimi 71*62c56f98SSadaf Ebrahimi if o_exp is not None: 72*62c56f98SSadaf Ebrahimi o = translate_ossl(s) 73*62c56f98SSadaf Ebrahimi self.assertEqual(o, o_exp) 74*62c56f98SSadaf Ebrahimi 75*62c56f98SSadaf Ebrahimi if m_exp is not None: 76*62c56f98SSadaf Ebrahimi m = translate_mbedtls(s) 77*62c56f98SSadaf Ebrahimi self.assertEqual(m, m_exp) 78*62c56f98SSadaf Ebrahimi 79*62c56f98SSadaf Ebrahimidef translate_gnutls(s_cipher): 80*62c56f98SSadaf Ebrahimi """ 81*62c56f98SSadaf Ebrahimi Translate s_cipher from standard ciphersuite naming convention 82*62c56f98SSadaf Ebrahimi and return the GnuTLS naming convention 83*62c56f98SSadaf Ebrahimi """ 84*62c56f98SSadaf Ebrahimi 85*62c56f98SSadaf Ebrahimi # Replace "_" with "-" to handle ciphersuite names based on Mbed TLS 86*62c56f98SSadaf Ebrahimi # naming convention 87*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("_", "-") 88*62c56f98SSadaf Ebrahimi 89*62c56f98SSadaf Ebrahimi s_cipher = re.sub(r'\ATLS-', '+', s_cipher) 90*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("-WITH-", ":+") 91*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("-EDE", "") 92*62c56f98SSadaf Ebrahimi 93*62c56f98SSadaf Ebrahimi # SHA in Mbed TLS == SHA1 GnuTLS, 94*62c56f98SSadaf Ebrahimi # if the last 3 chars are SHA append 1 95*62c56f98SSadaf Ebrahimi if s_cipher[-3:] == "SHA": 96*62c56f98SSadaf Ebrahimi s_cipher = s_cipher+"1" 97*62c56f98SSadaf Ebrahimi 98*62c56f98SSadaf Ebrahimi # CCM or CCM-8 should be followed by ":+AEAD" 99*62c56f98SSadaf Ebrahimi # Replace "GCM:+SHAxyz" with "GCM:+AEAD" 100*62c56f98SSadaf Ebrahimi if "CCM" in s_cipher or "GCM" in s_cipher: 101*62c56f98SSadaf Ebrahimi s_cipher = re.sub(r"GCM-SHA\d\d\d", "GCM", s_cipher) 102*62c56f98SSadaf Ebrahimi s_cipher = s_cipher+":+AEAD" 103*62c56f98SSadaf Ebrahimi 104*62c56f98SSadaf Ebrahimi # Replace the last "-" with ":+" 105*62c56f98SSadaf Ebrahimi else: 106*62c56f98SSadaf Ebrahimi index = s_cipher.rindex("-") 107*62c56f98SSadaf Ebrahimi s_cipher = s_cipher[:index] + ":+" + s_cipher[index+1:] 108*62c56f98SSadaf Ebrahimi 109*62c56f98SSadaf Ebrahimi return s_cipher 110*62c56f98SSadaf Ebrahimi 111*62c56f98SSadaf Ebrahimidef translate_ossl(s_cipher): 112*62c56f98SSadaf Ebrahimi """ 113*62c56f98SSadaf Ebrahimi Translate s_cipher from standard ciphersuite naming convention 114*62c56f98SSadaf Ebrahimi and return the OpenSSL naming convention 115*62c56f98SSadaf Ebrahimi """ 116*62c56f98SSadaf Ebrahimi 117*62c56f98SSadaf Ebrahimi # Replace "_" with "-" to handle ciphersuite names based on Mbed TLS 118*62c56f98SSadaf Ebrahimi # naming convention 119*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("_", "-") 120*62c56f98SSadaf Ebrahimi 121*62c56f98SSadaf Ebrahimi s_cipher = re.sub(r'^TLS-', '', s_cipher) 122*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("-WITH", "") 123*62c56f98SSadaf Ebrahimi 124*62c56f98SSadaf Ebrahimi # Remove the "-" from "ABC-xyz" 125*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("AES-", "AES") 126*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("CAMELLIA-", "CAMELLIA") 127*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("ARIA-", "ARIA") 128*62c56f98SSadaf Ebrahimi 129*62c56f98SSadaf Ebrahimi # Remove "RSA" if it is at the beginning 130*62c56f98SSadaf Ebrahimi s_cipher = re.sub(r'^RSA-', r'', s_cipher) 131*62c56f98SSadaf Ebrahimi 132*62c56f98SSadaf Ebrahimi # For all circumstances outside of PSK 133*62c56f98SSadaf Ebrahimi if "PSK" not in s_cipher: 134*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("-EDE", "") 135*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("3DES-CBC", "DES-CBC3") 136*62c56f98SSadaf Ebrahimi 137*62c56f98SSadaf Ebrahimi # Remove "CBC" if it is not prefixed by DES 138*62c56f98SSadaf Ebrahimi s_cipher = re.sub(r'(?<!DES-)CBC-', r'', s_cipher) 139*62c56f98SSadaf Ebrahimi 140*62c56f98SSadaf Ebrahimi # ECDHE-RSA-ARIA does not exist in OpenSSL 141*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("ECDHE-RSA-ARIA", "ECDHE-ARIA") 142*62c56f98SSadaf Ebrahimi 143*62c56f98SSadaf Ebrahimi # POLY1305 should not be followed by anything 144*62c56f98SSadaf Ebrahimi if "POLY1305" in s_cipher: 145*62c56f98SSadaf Ebrahimi index = s_cipher.rindex("POLY1305") 146*62c56f98SSadaf Ebrahimi s_cipher = s_cipher[:index+8] 147*62c56f98SSadaf Ebrahimi 148*62c56f98SSadaf Ebrahimi # If DES is being used, Replace DHE with EDH 149*62c56f98SSadaf Ebrahimi if "DES" in s_cipher and "DHE" in s_cipher and "ECDHE" not in s_cipher: 150*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("DHE", "EDH") 151*62c56f98SSadaf Ebrahimi 152*62c56f98SSadaf Ebrahimi return s_cipher 153*62c56f98SSadaf Ebrahimi 154*62c56f98SSadaf Ebrahimidef translate_mbedtls(s_cipher): 155*62c56f98SSadaf Ebrahimi """ 156*62c56f98SSadaf Ebrahimi Translate s_cipher from standard ciphersuite naming convention 157*62c56f98SSadaf Ebrahimi and return Mbed TLS ciphersuite naming convention 158*62c56f98SSadaf Ebrahimi """ 159*62c56f98SSadaf Ebrahimi 160*62c56f98SSadaf Ebrahimi # Replace "_" with "-" 161*62c56f98SSadaf Ebrahimi s_cipher = s_cipher.replace("_", "-") 162*62c56f98SSadaf Ebrahimi 163*62c56f98SSadaf Ebrahimi return s_cipher 164*62c56f98SSadaf Ebrahimi 165*62c56f98SSadaf Ebrahimidef format_ciphersuite_names(mode, names): 166*62c56f98SSadaf Ebrahimi t = {"g": translate_gnutls, 167*62c56f98SSadaf Ebrahimi "o": translate_ossl, 168*62c56f98SSadaf Ebrahimi "m": translate_mbedtls 169*62c56f98SSadaf Ebrahimi }[mode] 170*62c56f98SSadaf Ebrahimi return " ".join(c + '=' + t(c) for c in names) 171*62c56f98SSadaf Ebrahimi 172*62c56f98SSadaf Ebrahimidef main(target, names): 173*62c56f98SSadaf Ebrahimi print(format_ciphersuite_names(target, names)) 174*62c56f98SSadaf Ebrahimi 175*62c56f98SSadaf Ebrahimiif __name__ == "__main__": 176*62c56f98SSadaf Ebrahimi PARSER = argparse.ArgumentParser() 177*62c56f98SSadaf Ebrahimi PARSER.add_argument('target', metavar='TARGET', choices=['o', 'g', 'm']) 178*62c56f98SSadaf Ebrahimi PARSER.add_argument('names', metavar='NAMES', nargs='+') 179*62c56f98SSadaf Ebrahimi ARGS = PARSER.parse_args() 180*62c56f98SSadaf Ebrahimi main(ARGS.target, ARGS.names) 181