Mistake on this page?
Report an issue in GitHub or email us

TLS

Arm Mbed TLS provides a comprehensive SSL/TLS solution and makes it easy for developers to include cryptographic and SSL/TLS capabilities in their software and embedded products. As an SSL library, it provides an intuitive API, readable source code and a minimal and highly configurable code footprint.

We have adapted and preintegrated Mbed TLS with Mbed OS. You can import it from its standalone release. This edition of Mbed TLS does not include test code or the scripts used in the development of the library. You can find all of these in the standalone release.

Note: Mbed TLS needs a secure source of random numbers; make sure that your target board has one and that it is fully ported to Arm Mbed OS. You can read more about this in our porting guide.

Mbed TLS examples

You can try the following examples:

  1. TLS client: Downloads a file from an HTTPS server (os.mbed.com) and looks for a specific string in that file.

  2. Benchmark: Measures the time taken to perform basic cryptographic functions used in the library.

  3. Hashing: Demonstrates the various APIs for computing hashes of data (also known as message digests) with SHA-256.

  4. Authenticated encryption: Demonstrates using the Cipher API for encrypting and authenticating data with AES-CCM.

Each of them comes with complete usage instructions as a readme file in the repository.

Configuring Mbed TLS features

Mbed TLS simplifies enabling and disabling features to meet the needs of a particular project, through compilation options. The list of compilation flags is available in the fully documented configuration file, config.h.

For example, in an application called myapp, if you want to enable the EC J-PAKE key exchange and disable the CBC cipher mode, you can create a file named mbedtls-config-changes.h in the myapp directory containing the following lines:

#define MBEDTLS_ECJPAKE_C
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED

#undef MBEDTLS_CIPHER_MODE_CBC

Then create a file named mbed_app.json at the root of your application with the following contents:

{
    "macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls-config-changes.h\""]
}

Other resources

The Mbed TLS website contains many other useful resources for developers, such as developer documentation, knowledge base articles and a support forum.

uVisor

Warning: uVisor is superseded by the Secure Partition Manager (SPM) defined in the ARM Platform Security Architecture (PSA). uVisor is deprecated as of Mbed OS 5.10, and being replaced by a native PSA-compliant implementation of SPM.

The uVisor is a self-contained software hypervisor that creates independent secure domains on ARM Cortex®-M3 and Cortex®-M4 microcontrollers. It increases resilience against malware and protects secrets from leaking even among different modules of the same application. For more information, download the high-level overview (Download PDF).

Note about interrupts: When the uVisor is enabled, all NVIC APIs are rerouted to the corresponding uVisor vIRQ APIs, which virtualize interrupts. The uVisor interrupt model has the following features:

  • The uVisor owns the interrupt vector table.
  • All ISRs are relocated to SRAM.
  • Code in a box can only change the state of an IRQ (enable it, change its priority and so on) if the box registered that IRQ with uVisor through an IRQ ACL.
  • You can only modify an IRQ that belongs to a box when that box context is active.

Although this behavior is different from that of the original NVIC, it is backward compatible. Legacy code (such as a device HAL) still works after uVisor is enabled.

Usage

  1. Include uVisor library in your application.
  2. Specify capabilities in mandatory access control list.
  3. Add and configure secure boxes, special compartments with exclusive access to peripherals, memories and interrupts.
  4. Create public entry points for your secure boxes.
  5. Compile your application with uVisor enabled.

For detailed usage guides and best practices, see the README

API

https://github.com/ARMmbed/uvisor/blob/master/docs/lib/API.md

Examples

This is a simple example to show how to write a uVisor-secured threaded application with IRQ support. One LED blinks periodically from the public box main thread. A secure box exclusively owns the second LED, which toggles you press the user button.

main.cpp

/*
 * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "uvisor-lib/uvisor-lib.h"
#include "mbed.h"
#include "main-hw.h"
#include "mem_map.h"

#warning "Warning: uVisor is superseded by the Secure Partition Manager (SPM) defined in the ARM Platform Security Architecture (PSA). \
          uVisor is deprecated as of Mbed OS 5.10, and being replaced by a native PSA-compliant implementation of SPM."

/* Create ACLs for main box. */
MAIN_ACL(g_main_acl);

/* Enable uVisor. */
UVISOR_SET_MODE_ACL(UVISOR_ENABLED, g_main_acl);
UVISOR_SET_PAGE_HEAP(8 * 1024, 5);

static void example_halt_error(THaltError reason, const THaltInfo *halt_info);

UVISOR_PUBLIC_BOX_DEBUG_DRIVER(example_halt_error);

static void example_halt_error(THaltError reason, const THaltInfo *halt_info) {

	const MemMap * map = NULL;
	if (halt_info->bfar) {
		map = memory_map_name(halt_info->bfar);
	}

	printf("\n");
	printf("  Address:           0x%08X\n", halt_info->bfar);
	printf("  Region/Peripheral: %s\n", (map ? map->name : "[not available]"));
	printf("    Base address:    0x%08X\n", (map ? map->base : halt_info->bfar));
	printf("    End address:     0x%08X\n", (map ? map->end : halt_info->bfar));

	return;
}

/* Targets with an ARMv7-M MPU needs this space adjustment to prevent a runtime
 * memory overflow error. The code below has been output directly by uVisor. */
#if defined(TARGET_EFM32GG_STK3700) || defined(TARGET_DISCO_F429ZI)
uint8_t __attribute__((section(".keep.uvisor.bss.boxes"), aligned(32))) __boxes_overhead[8064];
#endif

int main(void)
{
    DigitalOut led(MAIN_LED);

    printf("\r\n***** IRQ blinky uVisor example *****\r\n");

    size_t count = 0;

    while (1) {
        printf("Main loop count: %d\r\n", count++);
        led = !led;

        /* Blink once per second. */
        Thread::wait(500);
    }

    return 0;
}

main-hw.h

/*
 * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __UVISOR_HELLOWORLD_MAIN_HW_H__
#define __UVISOR_HELLOWORLD_MAIN_HW_H__

#if defined(TARGET_K64F)

#define MAIN_LED           LED1
#define SECURE_LED         LED2
#define LED_ON             false
#define LED_OFF            true
#define SECURE_SWITCH      SW2
#define SECURE_SWITCH_PULL PullUp

#define MAIN_ACL(acl_list_name) \
    static const UvisorBoxAclItem acl_list_name[] = {     \
        {SIM,    sizeof(*SIM),    UVISOR_TACLDEF_PERIPH}, \
        {OSC,    sizeof(*OSC),    UVISOR_TACLDEF_PERIPH}, \
        {MCG,    sizeof(*MCG),    UVISOR_TACLDEF_PERIPH}, \
        {PORTA,  sizeof(*PORTA),  UVISOR_TACLDEF_PERIPH}, \
        {PORTB,  sizeof(*PORTB),  UVISOR_TACLDEF_PERIPH}, \
        {PORTC,  sizeof(*PORTC),  UVISOR_TACLDEF_PERIPH}, \
        {PORTD,  sizeof(*PORTD),  UVISOR_TACLDEF_PERIPH}, \
        {PORTE,  sizeof(*PORTE),  UVISOR_TACLDEF_PERIPH}, \
        {RTC,    sizeof(*RTC),    UVISOR_TACLDEF_PERIPH}, \
        {LPTMR0, sizeof(*LPTMR0), UVISOR_TACLDEF_PERIPH}, \
        {PIT,    sizeof(*PIT),    UVISOR_TACLDEF_PERIPH}, \
        {SMC,    sizeof(*SMC),    UVISOR_TACLDEF_PERIPH}, \
        {UART0,  sizeof(*UART0),  UVISOR_TACLDEF_PERIPH}, \
        {I2C0,   sizeof(*I2C0),   UVISOR_TACLDEF_PERIPH}, \
        {SPI0,   sizeof(*SPI0),   UVISOR_TACLDEF_PERIPH}, \
    }

#elif defined(TARGET_EFM32GG_STK3700)

#define MAIN_LED           LED1
#define SECURE_LED         LED2
#define LED_ON             true
#define LED_OFF            false
#define SECURE_SWITCH      SW0
#define SECURE_SWITCH_PULL PullUp

#define MAIN_ACL(acl_list_name) \
    static const UvisorBoxAclItem acl_list_name[] = {     \
        {CMU,                 sizeof(*CMU),    UVISOR_TACLDEF_PERIPH}, \
        {MSC,                 sizeof(*MSC),    UVISOR_TACLDEF_PERIPH}, \
        {GPIO,                sizeof(*GPIO),   UVISOR_TACLDEF_PERIPH}, \
        {TIMER0,              sizeof(*TIMER0), UVISOR_TACLDEF_PERIPH}, \
        {UART0,               sizeof(*UART0),  UVISOR_TACLDEF_PERIPH}, \
        {(void *) 0x0FE08000, 0x1000,          UVISOR_TACLDEF_PERIPH}, \
        {(void *) 0x42000000, 0x2000000,       UVISOR_TACLDEF_PERIPH}, \
    }

#elif defined(TARGET_DISCO_F429ZI)

#define MAIN_LED           LED1
#define SECURE_LED         LED2
#define LED_ON             true
#define LED_OFF            false
#define SECURE_SWITCH      USER_BUTTON
#define SECURE_SWITCH_PULL PullDown

#define MAIN_ACL(acl_list_name) \
    static const UvisorBoxAclItem acl_list_name[] = {     \
        {GPIOA,               sizeof(*GPIOA),  UVISOR_TACLDEF_PERIPH}, \
        {GPIOB,               sizeof(*GPIOB),  UVISOR_TACLDEF_PERIPH}, \
        {GPIOC,               sizeof(*GPIOC),  UVISOR_TACLDEF_PERIPH}, \
        {GPIOD,               sizeof(*GPIOD),  UVISOR_TACLDEF_PERIPH}, \
        {GPIOE,               sizeof(*GPIOE),  UVISOR_TACLDEF_PERIPH}, \
        {RTC,                 sizeof(*RTC),    UVISOR_TACLDEF_PERIPH}, \
        {TIM5,                sizeof(*TIM5),   UVISOR_TACLDEF_PERIPH}, \
        {USART1,              sizeof(*USART1), UVISOR_TACLDEF_PERIPH}, \
        {I2C1,                sizeof(*I2C1),   UVISOR_TACLDEF_PERIPH}, \
        {SPI1,                sizeof(*SPI1),   UVISOR_TACLDEF_PERIPH}, \
        {RCC,                 sizeof(*RCC),    UVISOR_TACLDEF_PERIPH}, \
        {FLASH,               sizeof(*FLASH),  UVISOR_TACLDEF_PERIPH}, \
        {PWR,                 sizeof(*PWR),    UVISOR_TACLDEF_PERIPH}, \
        {EXTI,                sizeof(*EXTI),   UVISOR_TACLDEF_PERIPH}, \
        {GPIOG,               sizeof(*GPIOG),  UVISOR_TACLDEF_PERIPH}, \
        {SYSCFG,              sizeof(*SYSCFG), UVISOR_TACLDEF_PERIPH}, \
        {(void *) 0x42000000, 0x01000000,      UVISOR_TACLDEF_PERIPH}, \
    }

#else /* Target-specific settings */

#error "Unsupported target. Checkout the README.md file for the list of supported targets for this app."

#endif /* Target-specific settings */

#endif /* __UVISOR_HELLOWORLD_MAIN_HW_H__ */

led.cpp

/*
 * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "uvisor-lib/uvisor-lib.h"
#include "mbed.h"
#include "main-hw.h"

typedef struct {
    InterruptIn * sw;
    DigitalOut * led;
} my_box_context;

static const UvisorBoxAclItem acl[] = {
};

static void my_box_main(const void *);

/* Box configuration
 * We need 1kB of stack both in the main and interrupt threads as both of them
 * use printf. */
UVISOR_BOX_NAMESPACE(NULL);
UVISOR_BOX_HEAPSIZE(3072);
UVISOR_BOX_MAIN(my_box_main, osPriorityNormal, 1024);
UVISOR_BOX_CONFIG(my_box, acl, 1024, my_box_context);

#define uvisor_ctx ((my_box_context *) __uvisor_ctx)

static void my_box_switch_irq(void)
{
    /* Flip LED state. */
    *uvisor_ctx->led = !*uvisor_ctx->led;

    /* Print LED state on serial port. */
    printf("\r\nPressed switch, printing from interrupt - LED now %s.\r\n\r\n",
           (int) (*uvisor_ctx->led) == LED_ON ? "on" : "off");
}

static void my_box_main(const void *)
{
    /* Allocate a box-specific LED. */
    if (!(uvisor_ctx->led = new DigitalOut(SECURE_LED))) {
        printf("ERROR: failed to allocate memories for LED\r\n");
    } else {
        /* Turn LED off by default */
        *uvisor_ctx->led = LED_OFF;

        /* Allocate a box-specific switch handler. */
        if (!(uvisor_ctx->sw = new InterruptIn(SECURE_SWITCH))) {
            printf("ERROR: failed to allocate memories for switch\r\n");
        } else {
            /* Register handler for switch. */
            uvisor_ctx->sw->mode(SECURE_SWITCH_PULL);
            uvisor_ctx->sw->fall(my_box_switch_irq);

            /* No problem to return here as everything is initialized. */
            return;
        }
        delete uvisor_ctx->led;
    }
}

Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.