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