• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env perl
2#
3# Copyright The Mbed TLS Contributors
4# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
5#
6# This file is provided under the Apache License 2.0, or the
7# GNU General Public License v2.0 or later.
8#
9# **********
10# Apache License 2.0:
11#
12# Licensed under the Apache License, Version 2.0 (the "License"); you may
13# not use this file except in compliance with the License.
14# You may obtain a copy of the License at
15#
16# http://www.apache.org/licenses/LICENSE-2.0
17#
18# Unless required by applicable law or agreed to in writing, software
19# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
20# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21# See the License for the specific language governing permissions and
22# limitations under the License.
23#
24# **********
25#
26# **********
27# GNU General Public License v2.0 or later:
28#
29# This program is free software; you can redistribute it and/or modify
30# it under the terms of the GNU General Public License as published by
31# the Free Software Foundation; either version 2 of the License, or
32# (at your option) any later version.
33#
34# This program is distributed in the hope that it will be useful,
35# but WITHOUT ANY WARRANTY; without even the implied warranty of
36# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37# GNU General Public License for more details.
38#
39# You should have received a copy of the GNU General Public License along
40# with this program; if not, write to the Free Software Foundation, Inc.,
41# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
42#
43# **********
44#
45# Purpose
46#
47# Comments and uncomments #define lines in the given header file and optionally
48# sets their value or can get the value. This is to provide scripting control of
49# what preprocessor symbols, and therefore what build time configuration flags
50# are set in the 'config.h' file.
51#
52# Usage: config.pl [-f <file> | --file <file>] [-o | --force]
53#                   [set <symbol> <value> | unset <symbol> | get <symbol> |
54#                       full | realfull]
55#
56# Full usage description provided below.
57#
58# The following options are disabled instead of enabled with "full".
59#
60# * Options that require additional build dependencies or unusual hardware.
61# * Options that make testing less effective.
62# * Options that are incompatible with other options, or more generally that
63#   interact with other parts of the code in such a way that a bulk enabling
64#   is not a good way to test them.
65# * Options that remove features.
66#
67# The baremetal configuration excludes options that require a library or
68# operating system feature that is typically not present on bare metal
69# systems. It also excludes debugging features that increase the code size
70# of other modules.
71# Features that are excluded from "full" won't be in "baremetal" either.
72
73use warnings;
74use strict;
75
76my $config_file = "include/mbedtls/config.h";
77my $usage = <<EOU;
78$0 [-f <file> | --file <file>] [-o | --force]
79                   [set <symbol> <value> | unset <symbol> | get <symbol> |
80                        full | realfull | baremetal]
81
82Commands
83    set <symbol> [<value>]  - Uncomments or adds a #define for the <symbol> to
84                              the configuration file, and optionally making it
85                              of <value>.
86                              If the symbol isn't present in the file an error
87                              is returned.
88    unset <symbol>          - Comments out the #define for the given symbol if
89                              present in the configuration file.
90    get <symbol>            - Finds the #define for the given symbol, returning
91                              an exitcode of 0 if the symbol is found, and 1 if
92                              not. The value of the symbol is output if one is
93                              specified in the configuration file.
94    full                    - Uncomments all #define's in the configuration file
95                              excluding some reserved symbols, until the
96                              'Module configuration options' section
97    realfull                - Uncomments all #define's with no exclusions
98    baremetal               - Sets full configuration suitable for baremetal build.
99
100Options
101    -f | --file <filename>  - The file or file path for the configuration file
102                              to edit. When omitted, the following default is
103                              used:
104                                $config_file
105    -o | --force            - If the symbol isn't present in the configuration
106                              file when setting its value, a #define is
107                              appended to the end of the file.
108
109EOU
110
111my @excluded = qw(
112MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
113MBEDTLS_DEPRECATED_REMOVED
114MBEDTLS_DEPRECATED_WARNING
115MBEDTLS_ECP_NO_INTERNAL_RNG
116MBEDTLS_HAVE_SSE2
117MBEDTLS_MEMORY_BACKTRACE
118MBEDTLS_MEMORY_BUFFER_ALLOC_C
119MBEDTLS_MEMORY_DEBUG
120MBEDTLS_NO_64BIT_MULTIPLICATION
121MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
122MBEDTLS_NO_PLATFORM_ENTROPY
123MBEDTLS_NO_UDBL_DIVISION
124MBEDTLS_PKCS11_C
125MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
126MBEDTLS_REMOVE_3DES_CIPHERSUITES
127MBEDTLS_REMOVE_ARC4_CIPHERSUITES
128MBEDTLS_RSA_NO_CRT
129MBEDTLS_SSL_HW_RECORD_ACCEL
130MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
131MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
132MBEDTLS_TEST_NULL_ENTROPY
133MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
134MBEDTLS_ZLIB_SUPPORT
135_ALT\s*$
136);
137
138# Things that should be disabled in "baremetal"
139my @excluded_baremetal = qw(
140MBEDTLS_DEBUG_C
141MBEDTLS_ENTROPY_NV_SEED
142MBEDTLS_FS_IO
143MBEDTLS_HAVEGE_C
144MBEDTLS_HAVE_TIME
145MBEDTLS_HAVE_TIME_DATE
146MBEDTLS_MEMORY_BACKTRACE
147MBEDTLS_MEMORY_BUFFER_ALLOC_C
148MBEDTLS_NET_C
149MBEDTLS_PLATFORM_FPRINTF_ALT
150MBEDTLS_PLATFORM_NV_SEED_ALT
151MBEDTLS_PLATFORM_TIME_ALT
152MBEDTLS_TEST_HOOKS
153MBEDTLS_THREADING_C
154MBEDTLS_THREADING_PTHREAD
155MBEDTLS_TIMING_C
156);
157
158# Things that should be enabled in "full" even if they match @excluded.
159# Platform ALTs enable global variables that allow configuring the behavior
160# but default to the default behavior, except for PLATFORM_SETUP_TEARDOWN_ALT
161# which requires the application to provide relevant functions like
162# non-platform ALTs.
163my @non_excluded = qw(
164PLATFORM_(?!SETUP_TEARDOWN_)[A-Z_0-9]+_ALT
165);
166
167# Things that should be enabled in "baremetal"
168my @non_excluded_baremetal = qw(
169MBEDTLS_NO_PLATFORM_ENTROPY
170);
171
172# Process the command line arguments
173
174my $force_option = 0;
175
176my ($arg, $name, $value, $action);
177
178while ($arg = shift) {
179
180    # Check if the argument is an option
181    if ($arg eq "-f" || $arg eq "--file") {
182        $config_file = shift;
183
184        -f $config_file or die "No such file: $config_file\n";
185
186    }
187    elsif ($arg eq "-o" || $arg eq "--force") {
188        $force_option = 1;
189
190    }
191    else
192    {
193        # ...else assume it's a command
194        $action = $arg;
195
196        if ($action eq "full" || $action eq "realfull" || $action eq "baremetal" ) {
197            # No additional parameters
198            die $usage if @ARGV;
199
200        }
201        elsif ($action eq "unset" || $action eq "get") {
202            die $usage unless @ARGV;
203            $name = shift;
204
205        }
206        elsif ($action eq "set") {
207            die $usage unless @ARGV;
208            $name = shift;
209            $value = shift if @ARGV;
210
211        }
212        else {
213            die "Command '$action' not recognised.\n\n".$usage;
214        }
215    }
216}
217
218# If no command was specified, exit...
219if ( not defined($action) ){ die $usage; }
220
221# Check the config file is present
222if (! -f $config_file)  {
223
224    chdir '..' or die;
225
226    # Confirm this is the project root directory and try again
227    if ( !(-d 'scripts' && -d 'include' && -d 'library' && -f $config_file) ) {
228        die "If no file specified, must be run from the project root or scripts directory.\n";
229    }
230}
231
232
233# Now read the file and process the contents
234
235open my $config_read, '<', $config_file or die "read $config_file: $!\n";
236my @config_lines = <$config_read>;
237close $config_read;
238
239# Add required baremetal symbols to the list that is included.
240if ( $action eq "baremetal" ) {
241    @non_excluded = ( @non_excluded, @non_excluded_baremetal );
242}
243
244my ($exclude_re, $no_exclude_re, $exclude_baremetal_re);
245if ($action eq "realfull") {
246    $exclude_re = qr/^$/;
247    $no_exclude_re = qr/./;
248} else {
249    $exclude_re = join '|', @excluded;
250    $no_exclude_re = join '|', @non_excluded;
251}
252if ( $action eq "baremetal" ) {
253    $exclude_baremetal_re = join '|', @excluded_baremetal;
254}
255
256my $config_write = undef;
257if ($action ne "get") {
258    open $config_write, '>', $config_file or die "write $config_file: $!\n";
259}
260
261my $done;
262for my $line (@config_lines) {
263    if ($action eq "full" || $action eq "realfull" || $action eq "baremetal" ) {
264        if ($line =~ /name SECTION: Module configuration options/) {
265            $done = 1;
266        }
267
268        if (!$done && $line =~ m!^//\s?#define! &&
269                ( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) &&
270                ( $action ne "baremetal" || ( $line !~ /$exclude_baremetal_re/ ) ) ) {
271            $line =~ s!^//\s?!!;
272        }
273        if (!$done && $line =~ m!^\s?#define! &&
274                ! ( ( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) &&
275                    ( $action ne "baremetal" || ( $line !~ /$exclude_baremetal_re/ ) ) ) ) {
276            $line =~ s!^!//!;
277        }
278    } elsif ($action eq "unset") {
279        if (!$done && $line =~ /^\s*#define\s*$name\b/) {
280            $line = '//' . $line;
281            $done = 1;
282        }
283    } elsif (!$done && $action eq "set") {
284        if ($line =~ m!^(?://)?\s*#define\s*$name\b!) {
285            $line = "#define $name";
286            $line .= " $value" if defined $value && $value ne "";
287            $line .= "\n";
288            $done = 1;
289        }
290    } elsif (!$done && $action eq "get") {
291        if ($line =~ /^\s*#define\s*$name(?:\s+(.*?))\s*(?:$|\/\*|\/\/)/) {
292            $value = $1;
293            $done = 1;
294        }
295    }
296
297    if (defined $config_write) {
298        print $config_write $line or die "write $config_file: $!\n";
299    }
300}
301
302# Did the set command work?
303if ($action eq "set" && $force_option && !$done) {
304
305    # If the force option was set, append the symbol to the end of the file
306    my $line = "#define $name";
307    $line .= " $value" if defined $value && $value ne "";
308    $line .= "\n";
309    $done = 1;
310
311    print $config_write $line or die "write $config_file: $!\n";
312}
313
314if (defined $config_write) {
315    close $config_write or die "close $config_file: $!\n";
316}
317
318if ($action eq "get") {
319    if ($done) {
320        if ($value ne '') {
321            print "$value\n";
322        }
323        exit 0;
324    } else {
325        # If the symbol was not found, return an error
326        exit 1;
327    }
328}
329
330if ($action eq "full" && !$done) {
331    die "Configuration section was not found in $config_file\n";
332
333}
334
335if ($action ne "full" && $action ne "unset" && !$done) {
336    die "A #define for the symbol $name was not found in $config_file\n";
337}
338
339__END__
340