Git Product home page Git Product logo

wolfssl / wolfboot Goto Github PK

View Code? Open in Web Editor NEW
317.0 24.0 89.0 4.88 MB

wolfBoot is a portable, OS-agnostic, secure bootloader for microcontrollers, supporting firmware authentication and firmware update mechanisms.

Home Page: https://www.wolfssl.com

License: GNU General Public License v3.0

Makefile 10.87% C 81.07% Assembly 2.34% Python 1.61% Batchfile 0.01% Shell 1.58% GDB 0.01% Dockerfile 0.01% CMake 2.52%
secure-bootloader wolfboot cryptography bootloader firmware-verification portable compact embedded multi-slot-partitioning os-independent

wolfboot's Introduction

wolfSSL Embedded SSL/TLS Library

The wolfSSL embedded SSL library (formerly CyaSSL) is a lightweight SSL/TLS library written in ANSI C and targeted for embedded, RTOS, and resource-constrained environments - primarily because of its small size, speed, and feature set. It is commonly used in standard operating environments as well because of its royalty-free pricing and excellent cross platform support. wolfSSL supports industry standards up to the current TLS 1.3 and DTLS 1.3, is up to 20 times smaller than OpenSSL, and offers progressive ciphers such as ChaCha20, Curve25519, Blake2b and Post-Quantum TLS 1.3 groups. User benchmarking and feedback reports dramatically better performance when using wolfSSL over OpenSSL.

wolfSSL is powered by the wolfCrypt cryptography library. Two versions of wolfCrypt have been FIPS 140-2 validated (Certificate #2425 and certificate #3389). FIPS 140-3 validation is in progress. For additional information, visit the wolfCrypt FIPS FAQ or contact [email protected].

Why Choose wolfSSL?

There are many reasons to choose wolfSSL as your embedded, desktop, mobile, or enterprise SSL/TLS solution. Some of the top reasons include size (typical footprint sizes range from 20-100 kB), support for the newest standards (SSL 3.0, TLS 1.0, TLS 1.1, TLS 1.2, TLS 1.3, DTLS 1.0, DTLS 1.2, and DTLS 1.3), current and progressive cipher support (including stream ciphers), multi-platform, royalty free, and an OpenSSL compatibility API to ease porting into existing applications which have previously used the OpenSSL package. For a complete feature list, see Chapter 4 of the wolfSSL manual.

Notes, Please Read

Note 1

wolfSSL as of 3.6.6 no longer enables SSLv3 by default. wolfSSL also no longer supports static key cipher suites with PSK, RSA, or ECDH. This means if you plan to use TLS cipher suites you must enable DH (DH is on by default), or enable ECC (ECC is on by default), or you must enable static key cipher suites with one or more of the following defines:

WOLFSSL_STATIC_DH
WOLFSSL_STATIC_RSA
WOLFSSL_STATIC_PSK

Though static key cipher suites are deprecated and will be removed from future versions of TLS. They also lower your security by removing PFS.

When compiling ssl.c, wolfSSL will now issue a compiler error if no cipher suites are available. You can remove this error by defining WOLFSSL_ALLOW_NO_SUITES in the event that you desire that, i.e., you're not using TLS cipher suites.

Note 2

wolfSSL takes a different approach to certificate verification than OpenSSL does. The default policy for the client is to verify the server, this means that if you don't load CAs to verify the server you'll get a connect error, no signer error to confirm failure (-188).

If you want to mimic OpenSSL behavior of having SSL_connect succeed even if verifying the server fails and reducing security you can do this by calling:

wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);

before calling wolfSSL_new();. Though it's not recommended.

Note 3

The enum values SHA, SHA256, SHA384, SHA512 are no longer available when wolfSSL is built with --enable-opensslextra (OPENSSL_EXTRA) or with the macro NO_OLD_SHA_NAMES. These names get mapped to the OpenSSL API for a single call hash function. Instead the name WC_SHA, WC_SHA256, WC_SHA384 and WC_SHA512 should be used for the enum name.

wolfSSL Release 5.7.0 (Mar 20, 2024)

Release 5.7.0 has been developed according to wolfSSL's development and QA process (see link below) and successfully passed the quality criteria. https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assurance

NOTE: * --enable-heapmath is being deprecated and will be removed by end of 2024

NOTE: In future releases, --enable-des3 (which is disabled by default) will be insufficient in itself to enable DES3 in TLS cipher suites. A new option, --enable-des3-tls-suites, will need to be supplied in addition. This option should only be used in backward compatibility scenarios, as it is inherently insecure.

NOTE: This release switches the default ASN.1 parser to the new ASN template code. If the original ASN.1 code is preferred define WOLFSSL_ASN_ORIGINAL to use it. See PR #7199.

Vulnerabilities

  • [High] CVE-2024-0901 Potential denial of service and out of bounds read. Affects TLS 1.3 on the server side when accepting a connection from a malicious TLS 1.3 client. If using TLS 1.3 on the server side it is recommended to update the version of wolfSSL used. Fixed in this GitHub pull request #7099

  • [Med] CVE-2024-1545 Fault Injection vulnerability in RsaPrivateDecryption function that potentially allows an attacker that has access to the same system with a victims process to perform a Rowhammer fault injection. Thanks to Junkai Liang, Zhi Zhang, Xin Zhang, Qingni Shen for the report (Peking University, The University of Western Australia)." Fixed in this GitHub pull request #7167

  • [Med] Fault injection attack with EdDSA signature operations. This affects ed25519 sign operations where the system could be susceptible to Rowhammer attacks. Thanks to Junkai Liang, Zhi Zhang, Xin Zhang, Qingni Shen for the report (Peking University, The University of Western Australia). Fixed in this GitHub pull request #7212

New Feature Additions

  • Added --enable-experimental configure flag to gate out features that are currently experimental. Now liboqs, kyber, lms, xmss, and dual-alg-certs require the --enable-experimental flag.

POST QUANTUM SUPPORT ADDITIONS

  • Experimental framework for using wolfSSL’s XMSS implementation (PR 7161)
  • Experimental framework for using wolfSSL’s LMS implementation (PR 7283)
  • Experimental wolfSSL Kyber implementation and assembly optimizations, enabled with --enable-experimental --enable-kyber (PR 7318)
  • Experimental support for post quantum dual key/signature certificates. A few known issues and sanitizer checks are in progress with this feature. Enabled with the configure flags --enable-experimental --enable-dual-alg-certs (PR 7112)
  • CryptoCb support for PQC algorithms (PR 7110)

OTHER FEATURE ADDITIONS

  • The Linux kernel module now supports registration of AES-GCM, AES-XTS, AES-CBC, and AES-CFB with the kernel cryptosystem through the new --enable-linuxkm-lkcapi-register option, enabling automatic use of wolfCrypt implementations by the dm-crypt/luks and ESP subsystems. In particular, wolfCrypt AES-XTS with –enable-aesni is faster than the native kernel implementation.
  • CryptoCb hook to one-shot CMAC functions (PR 7059)
  • BER content streaming support for PKCS7_VerifySignedData and sign/encrypt operations (PR 6961 & 7184)
  • IoT-Safe SHA-384 and SHA-512 support (PR 7176)
  • I/O callbacks for content and output with PKCS7 bundle sign/encrypt to reduce peak memory usage (PR 7272)
  • Microchip PIC24 support and example project (PR 7151)
  • AutoSAR shim layer for RNG, SHA256, and AES (PR 7296)
  • wolfSSL_CertManagerUnloadIntermediateCerts API to clear intermediate certs added to certificate store (PR 7245)
  • Implement SSL_get_peer_signature_nid and SSL_get_peer_signature_type_nid (PR 7236)

Enhancements and Optimizations

  • Remove obsolete user-crypto functionality and Intel IPP support (PR 7097)
  • Support for RSA-PSS signatures with CRL use (PR 7119)
  • Enhancement for AES-GCM use with Xilsecure on Microblaze (PR 7051)
  • Support for crypto cb only build with ECC and NXP CAAM (PR 7269)
  • Improve liboqs integration adding locking and init/cleanup functions (PR 7026)
  • Prevent memory access before clientSession->serverRow and clientSession->serverIdx are sanitized (PR 7096)
  • Enhancements to reproducible build (PR 7267)
  • Update Arduino example TLS Client/Server and improve support for ESP32 (PR 7304 & 7177)
  • XC32 compiler version 4.x compatibility (PR 7128)
  • Porting for build on PlayStation 3 and 4 (PR 7072)
  • Improvements for Espressif use; SHA HW/SW selection and use on ESP32-C2/ESP8684, wolfSSL_NewThread() type, component cmake fix, and update TLS client example for ESP8266 (PR 7081, 7173, 7077, 7148, 7240)
  • Allow crypto callbacks with SHA-1 HW (PR 7087)
  • Update OpenSSH port to version 9.6p1(PR 7203)
  • ARM Thumb2 enhancements, AES-GCM support for GCM_SMALL, alignment fix on key, fix for ASM clobber list (PR 7291,7301,7221)
  • Expand heap hint support for static memory build with more x509 functions (PR 7136)
  • Improving ARMv8 ChaCha20 ASM (alignment) (PR 7182)
  • Unknown extension callback wolfSSL_CertManagerSetUnknownExtCallback added to CertManager (PR 7194)
  • Implement wc_rng_new_ex for use with devID’s with crypto callback (PR 7271)
  • Allow reading 0-RTT data after writing 0.5-RTT data (PR 7102)
  • Send alert on bad PSK binder error (PR 7235)
  • Enhancements to CMake build files for use with cross compiling (PR 7188)

Fixes

  • Fix for checking result of MAC verify when no AAD is used with AES-GCM and Xilinx Xilsecure (PR 7051)
  • Fix for Aria sign use (PR 7082)
  • Fix for invalid dh_ffdhe_test test case using Intel QuickAssist (PR 7085)
  • Fixes for TI AES and SHA on TM4C with HW acceleration and add full AES GCM and CCM support with TLS (PR 7018)
  • Fixes for STM32 PKA use with ECC (PR 7098)
  • Fixes for TLS 1.3 with crypto callbacks to offload KDF / HMAC operation (PR 7070)
  • Fix include path for FSP 3.5 on Renesas RA6M4 (PR 7101)
  • Siphash x64 asm fix for use with older compilers (PR 7299)
  • Fix for SGX build with SP (PR 7308)
  • Fix to Make it mandatory that the cookie is sent back in new ClientHello when seen in a HelloRetryRequest with (PR 7190)
  • Fix for wrap around behavior with BIO pairs (PR 7169)
  • OCSP fixes for parsing of response correctly when there was a revocation reason and returning correct error value with date checks (PR 7241 & 7255)
  • Fix build with NO_STDIO_FILESYSTEM and improve checks for XGETENV (PR 7150)
  • Fix for DTLS sequence number and cookie when downgrading DTLS version (PR 7214)
  • Fix for write_dup use with chacha-poly cipher suites (PR 7206)
  • Fix for multiple handshake messages in one record failing with OUT_OF_ORDER_E when downgrading from TLS 1.3 to TLS 1.2 (PR 7141)
  • Fix for AES ECB build with Thumb and alignment (PR 7094)
  • Fix for negotiate handshake until the end in wolfSSL_read/wolfSSL_write if hitting an edge case with want read/write (PR 7237)

For additional vulnerability information visit the vulnerability page at: https://www.wolfssl.com/docs/security-vulnerabilities/

See INSTALL file for build instructions. More info can be found on-line at: https://wolfssl.com/wolfSSL/Docs.html

Resources

wolfSSL Website

wolfSSL Wiki

FIPS 140-2/140-3 FAQ

wolfSSL Documentation

wolfSSL Manual

wolfSSL API Reference

wolfCrypt API Reference

TLS 1.3

wolfSSL Vulnerabilities

Additional wolfSSL Examples

Directory structure

<wolfssl_root>
├── certs   [Certificates used in tests and examples]
├── cmake   [Cmake build utilities]
├── debian  [Debian packaging files]
├── doc     [Documentation for wolfSSL (Doxygen)]
├── Docker  [Prebuilt Docker environments]
├── examples    [wolfSSL examples]
│   ├── asn1    [ASN.1 printing example]
│   ├── async   [Asynchronous Cryptography example]
│   ├── benchmark   [TLS benchmark example]
│   ├── client  [Client example]
│   ├── configs [Example build configurations]
│   ├── echoclient  [Echoclient example]
│   ├── echoserver  [Echoserver example]
│   ├── pem [Example for convert between PEM and DER]
│   ├── sctp    [Servers and clients that demonstrate wolfSSL's DTLS-SCTP support]
│   └── server  [Server example]
├── IDE     [Contains example projects for various development environments]
├── linuxkm [Linux Kernel Module implementation]
├── m4      [Autotools utilities]
├── mcapi   [wolfSSL MPLAB X Project Files]
├── mplabx  [wolfSSL MPLAB X Project Files]
├── mqx     [wolfSSL Freescale CodeWarrior Project Files]
├── rpm     [RPM packaging metadata]
├── RTOS
│   └── nuttx   [Port of wolfSSL for NuttX]
├── scripts [Testing scripts]
├── src     [wolfSSL source code]
├── sslSniffer  [wolfSSL sniffer can be used to passively sniff SSL traffic]
├── support [Contains the pkg-config file]
├── tests   [Unit and configuration testing]
├── testsuite   [Test application that orchestrates tests]
├── tirtos  [Port of wolfSSL for TI RTOS]
├── wolfcrypt   [The wolfCrypt component]
│   ├── benchmark   [Cryptography benchmarking application]
│   ├── src         [wolfCrypt source code]
│   │   └── port    [Supported hardware acceleration ports]
│   └── test        [Cryptography testing application]
├── wolfssl [Header files]
│   ├── openssl [Compatibility layer headers]
│   └── wolfcrypt   [Header files]
├── wrapper [wolfSSL language wrappers]
└── zephyr  [Port of wolfSSL for Zephyr RTOS]

wolfboot's People

Contributors

bigbrett avatar billphipps avatar cconlon avatar cmcquinn avatar danielinux avatar dgarske avatar dimitripapadopoulos avatar glennergeerts avatar hajer97 avatar jacobbarthelmeh avatar jpbland1 avatar kareem-wolfssl avatar kojo1 avatar lealem47 avatar loorts-aloxy avatar miyazakh avatar philljj avatar rizlik avatar tatowicz avatar tmael avatar toddouska avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wolfboot's Issues

Values of `version_field` and `type_field` are ignored by compiler optimization

I'm trying to use wolfBoot on QEMU virt machine model for RISC-V.
When updating firmware from emulated flash, I found that update partition was not measured correctly.

Checking compiled binary, I noticed that the type_field and version_field values are ignored.
Each variable is used in libwolfboot.c#wolfBoot_get_image_type() and libwolfboot.c#wolfBoot_get_blob_version().

I also find same variable in functions related delta update, but I did not try delta update and don't know whether this has same issue.

Details

By default, gcc optimization seems to set to -Os. This options generate the assembly below.

0000000080000de2 <wolfBoot_get_blob_version>:
    80000de2:   4118                    lw      a4,0(a0)
    80000de4:   1101                    addi    sp,sp,-32
    80000de6:   464c57b7                lui     a5,0x464c5
    80000dea:   ec06                    sd      ra,24(sp)
    80000dec:   e402                    sd      zero,8(sp)
    80000dee:   f5778793                addi    a5,a5,-169 # 464c4f57 <STACK_SIZE+0x464c4b57>
    80000df2:   00f71763                bne     a4,a5,80000e00 <wolfBoot_get_blob_version+0x1e>
    80000df6:   0030                    addi    a2,sp,8
    80000df8:   4585                    li      a1,1
    80000dfa:   0521                    addi    a0,a0,8
    80000dfc:   f73ff0ef                jal     ra,80000d6e <wolfBoot_find_header>
    80000e00:   60e2                    ld      ra,24(sp)
    80000e02:   4501                    li      a0,0
    80000e04:   6105                    addi    sp,sp,32
    80000e06:   8082                    ret

The function expects to return the value of the version_field, but 0 is stored directly in a0 through any flow, and 0 is always returned. I investigated using the debugger and found that this was the cause of the problem.

I fixed this problem by simply adding volatile to version_field or type_field.
This is example of version_field.

uint32_t wolfBoot_get_blob_version(uint8_t *blob)
{
    uint32_t * volatile version_field = NULL;
    uint32_t *magic = NULL;

    magic = (uint32_t *)blob;
    if (*magic != WOLFBOOT_MAGIC)
        return 0;
    if (wolfBoot_find_header(blob + IMAGE_HEADER_OFFSET, HDR_VERSION,
            (void *)&version_field) == 0)
        return 0;
    if (version_field)
        return im2n(*version_field);
    return 0;
}

Assembly changed to this.

0000000080000de2 <wolfBoot_get_blob_version>:
    80000de2:   4118                    lw      a4,0(a0)
    80000de4:   1101                    addi    sp,sp,-32
    80000de6:   464c57b7                lui     a5,0x464c5
    80000dea:   ec06                    sd      ra,24(sp)
    80000dec:   e402                    sd      zero,8(sp)
    80000dee:   f5778793                addi    a5,a5,-169 # 464c4f57 <STACK_SIZE+0x464c4b57>
    80000df2:   00f70663                beq     a4,a5,80000dfe <wolfBoot_get_blob_version+0x1c>
    80000df6:   4501                    li      a0,0
    80000df8:   60e2                    ld      ra,24(sp)
    80000dfa:   6105                    addi    sp,sp,32
    80000dfc:   8082                    ret
    80000dfe:   0030                    addi    a2,sp,8
    80000e00:   4585                    li      a1,1
    80000e02:   0521                    addi    a0,a0,8
    80000e04:   f6bff0ef                jal     ra,80000d6e <wolfBoot_find_header>
    80000e08:   d57d                    beqz    a0,80000df6 <wolfBoot_get_blob_version+0x14>
    80000e0a:   67a2                    ld      a5,8(sp)
    80000e0c:   d7ed                    beqz    a5,80000df6 <wolfBoot_get_blob_version+0x14>
    80000e0e:   67a2                    ld      a5,8(sp)
    80000e10:   4388                    lw      a0,0(a5)
    80000e12:   b7dd                    j       80000df8 <wolfBoot_get_blob_version+0x16>

It correctly returned value of version_field.

I can't determine if this problem is specific to my environment, so I will share it with you.

Compiler toolchain: RISC-V GNU Toolchain Tag:2022.06.10
Options in arch.mk is below. Some sources are modified by me for riscv64.

## RISCV
ifeq ($(ARCH),RISCV)
  ifeq ($(TARGET), riscv_virt)
    ## For Qemu virt emulation
    CROSS_COMPILE:=riscv64-unknown-elf-
    CFLAGS+=-fno-builtin-printf -DUSE_M_TIME -g -march=rv64imac -mabi=lp64 -mcmodel=medany -nostartfiles -DARCH_RISCV -DRISCV_QEMU_VIRT
    LDFLAGS+=-march=rv64imac -mabi=lp64 -mcmodel=medany
    MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
    CFLAGS +=-ffunction-sections -fdata-sections
    LDFLAGS+=-Wl,--gc-sections
    OBJS+=src/boot_riscv64.o src/vector_riscv64.o
  else

Thanks.

Uefi shell wolfssl efi

Version

Latest

Description

Can anyone please point out some use cases for having wolfssl.efi build?
Also, is there any guide for that?

Thanks

Problem with ECC protected flash on STM32H743

Hi

I'm currently trying to integrate wolfBoot on a STM32H743 microcontroller. On this chip the flash is ECC protected. Therefore you cannot write to the same flash word (256 bit) more than once, because the ECC value is calculated and stored the first time you write to it. wolfBoot does so when triggering an update: Once to set the partition magic and once to set the partition state. This then results in a fault when reading because the ECC value is invalid.

What is the proper solution to solve this problem? If there is none, are you planning to add support for this use case?

Thanks!

support for cortex M4

This is a very interesting project. Do you have a cortex M4 integration on your roadmap?

Possible problem with power fail

Good morning,

I am using WolfBoot 2.0.2 on STM32U585.

I am using dual swap capability and in normal condition all works like a charm.

My Flash partition is:

0x08000000 --> Wolfboot
0x08010000 --> Boot Image
0x08110000 --> Update image

The only (maybe) problem seems to occurs under this condition.

  1. load a good image candidate at attress 0x08110000.
  2. reboot the MCU

Then WolfBoot will execute

void RAMFUNCTION hal_flash_dualbank_swap(void)
{
    uint32_t cur_opts;
    hal_flash_unlock();
    hal_flash_opt_unlock();
    cur_opts = (FLASH_OPTR & FLASH_OPTR_SWAP_BANK) >> 20;
    if (cur_opts)
        FLASH_OPTR &= (~FLASH_OPTR_SWAP_BANK);
    else
        FLASH_OPTR |= FLASH_OPTR_SWAP_BANK;
    hal_flash_opt_lock();
    hal_flash_lock();
    stm32u5_reboot();
}

setting FLASH_OPTR_SWAP_BANK bit and reboot again the MCU.
I notice that if a power failure occurs during the execution of fork_bootloader()

void hal_init(void)
{
#if defined(DUALBANK_SWAP) && defined(__WOLFBOOT)
    if ((FLASH_OPTR & (FLASH_OPTR_SWAP_BANK | FLASH_OPTR_DBANK)) == FLASH_OPTR_DBANK)
        fork_bootloader();

then the MCU is locked forever because FLASH_OPTR_SWAP_BANK was previously set to 1 and at location 0x08100000 there is wrong code or no code at all due to powerfailure.

My solution was to comment this line of code


//    if ((FLASH_OPTR & (FLASH_OPTR_SWAP_BANK | FLASH_OPTR_DBANK)) == FLASH_OPTR_DBANK)
//        fork_bootloader();

and to preload the WolfBoot binary at
0x08000000 --> Wolfboot
0x08100000 --> Wolfboot

In this way I solved the problem.

Am I missing something? Maybe I am doing something wrong.

Thank you

Running WolfBoot on ST NUCLEO-F401RE

Hello,

I'm trying to run wolfboot on an STM32F401RE along with a user application generated with cubeMX.
here is my repo: https://github.com/kaizoku-oh/wolfboot-iar-example
Basically I have an IAR workspace that contains 2 projects bootloader(wolfboot) and application (blinky + printf).
I also added 3 batch scripts to remove and generate keys as well as sign the application binary.

I can compile both projects (bootloader and application) with no problem.
But after flashing the binaries nothing happens, (if the app starts the led should be blinking and should be able to see UART messages).
I don't know if I'm missing something or if there is a way to debug the bootloader to see why it didn't jump to the application.

Here is the configuration I used and the steps I followed for both bootloader and application:

Bootloader

IAR preprocessor defines:

__WOLFBOOT
PLATFORM_stm32f4
ARCH_ARM
WOLFSSL_USER_SETTINGS
DEBUG_CONSOLE_ASSERT_DISABLE=1
WOLFBOOT_SIGN_ECC256
WOLFBOOT_HASH_SHA256
WOLFSSL_SP_ASM
WOLFSSL_SP_ARM_CORTEX_M_ASM
ARCH_FLASH_OFFSET=0x08000000
WOLFBOOT_FIXED_PARTITIONS

target.h: (common file used by bootloader and application)

#ifndef H_TARGETS_TARGET_
#define H_TARGETS_TARGET_

#define WOLFBOOT_SECTOR_SIZE                 0x20000
#define WOLFBOOT_PARTITION_BOOT_ADDRESS      0x20000
#define WOLFBOOT_PARTITION_SIZE              0x20000 
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS    0x40000
#define WOLFBOOT_PARTITION_SWAP_ADDRESS      0x60000

#endif /* !H_TARGETS_TARGET_ */

1. generate keys: generate_key.bat

PS D:\wolfboot-iar-example\tools> .\generate_key.bat

2. build the bootloader project

Application

IAR preprocessor defines:

__WOLFBOOT
USE_HAL_DRIVER
STM32F401xE
WOLFBOOT_FIXED_PARTITIONS
PLATFORM_stm32f4
ARCH_ARM
WOLFSSL_USER_SETTINGS
DEBUG_CONSOLE_ASSERT_DISABLE=1
WOLFBOOT_SIGN_ECC256
WOLFBOOT_HASH_SHA256
WOLFSSL_SP_ASM
WOLFSSL_SP_ARM_CORTEX_M_ASM

IAR ICF linker file: (as you can see I modified the flash start address from 0x08000000 to 0x08020100

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08020100;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__    = 0x08020100;
define symbol __ICFEDIT_region_ROM_end__      = 0x0803FFFF;
define symbol __ICFEDIT_region_RAM_start__    = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__      = 0x20017FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/


define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

system_stm32f4xx.c:

#define USER_VECT_TAB_ADDRESS

#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00020100U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */

1. build the application project

2. sign app binary: sign_app.bat

PS D:\wolfboot-iar-example\tools> .\sign_app.bat 1

Flashing

I followed the same steps mentioned in the docs here

Cannot compile IAR example project

The IAR example project for stm32f4 found under IDE/IAR is not able to compile.
After generating the keypair using the generate_key.bat script I wasn't able to compile the project.
I'm using IAR 8.50.9 on Windows 10 x64.
I feel like I'm missing something?

SharedScreenshot1
SharedScreenshot2

PIC32MZ HAL

Curious if you are going to be implementing a pre-configured PIC32 HAL target in the future?

I would adopt this boot-loader for our devices if this was the case.
Thanks,
Gordon

Bootloader firmware not built without test-apps / cannot reconfigure cmake build

Hi!
I have issues when trying to build the bootloader firmware via cmake.

I tried to build the project using the following command:

mkdir build && cd build && cmake -DWOLFBOOT_TARGET=stm32h7 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 .. && make

It's the example command available in the README.md file without the -DTEST_APPS flag to avoid building the baremetal test application, as I only want the bootloader.bin. With this, wolfboot.bin and wolfboot.elf are not being built (but they are in the Makefile version: cp config/examples/stm32h7.config .config && make wolfboot.bin). How can I avoid building the test apps when I only want the wolfboot bootloader firmware using cmake?

The logs are:

-- The C compiler identification is GNU 13.2.1
-- The CXX compiler identification is GNU 13.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Building for stm32h7
-- Cross-compiling using GNU arm-none-eabi toolchain
-- Signing image using ECC256
-- Using SHA256 hash
-- Using C Keytools
-- Using fast math
-- Configuring done (0.5s)
-- Generating done (0.0s)
-- Build files have been written to: /<REDACTED>/wolfBoot/build
[...]
[  5%] Building C object CMakeFiles/wolfboothal.dir/hal/stm32h7.c.o
[ 10%] Linking C static library libwolfboothal.a
[ 10%] Built target wolfboothal
[ 15%] Building signing tool
[ 21%] Building keygen tool
[ 21%] Built target keytools
[ 26%] Generating keystore.c and signing private key
<REDACTED>
[ 31%] Building C object CMakeFiles/public_key.dir/keystore.c.o
[ 36%] Linking C static library libpublic_key.a
[ 42%] Built target public_key
[ 47%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/integer.c.o
[ 52%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/tfm.c.o
[ 57%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/ecc.c.o
[ 63%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/memory.c.o
[ 68%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/wc_port.c.o
[ 73%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/wolfmath.c.o
[ 78%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/hash.c.o
[ 84%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/sha256.c.o
[ 89%] Linking C static library libwolfcrypt.a
[ 89%] Built target wolfcrypt
[ 94%] Building C object CMakeFiles/wolfboot.dir/src/libwolfboot.c.o
[100%] Linking C static library libwolfboot.a
[100%] Built target wolfboot

I also have issues when I try to reconfigure the project. Rerunning the cmake command above generates the following logs:

✦ ❯ cmake -DWOLFBOOT_TARGET=stm32h7 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 ..
-- Building for stm32h7
-- Cross-compiling using GNU arm-none-eabi toolchain
-- Signing image using ECC256
-- Using SHA256 hash
-- Using C Keytools
-- Using fast math
-- Configuring done (0.0s)
You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:
CMAKE_C_COMPILER= /usr/bin/arm-none-eabi-gcc
CMAKE_CXX_COMPILER= /usr/bin/arm-none-eabi-g++

-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc - broken
CMake Error at /usr/share/cmake/Modules/CMakeTestCCompiler.cmake:67 (message):
  The C compiler

    "/usr/bin/arm-none-eabi-gcc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: '/<REDACTED>/wolfBoot/build/CMakeFiles/CMakeScratch/TryCompile-e4htJH'
    
    Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_3a1e1/fast
    /usr/bin/make  -f CMakeFiles/cmTC_3a1e1.dir/build.make CMakeFiles/cmTC_3a1e1.dir/build
    make[1]: Entering directory '/<REDACTED>/wolfBoot/build/CMakeFiles/CMakeScratch/TryCompile-e4htJH'
    Building C object CMakeFiles/cmTC_3a1e1.dir/testCCompiler.c.o
    /usr/bin/arm-none-eabi-gcc    -o CMakeFiles/cmTC_3a1e1.dir/testCCompiler.c.o -c /<REDACTED>/wolfBoot/build/CMakeFiles/CMakeScratch/TryCompile-e4htJH/testCCompiler.c
    Linking C executable cmTC_3a1e1
    /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_3a1e1.dir/link.txt --verbose=1
    /usr/bin/arm-none-eabi-gcc CMakeFiles/cmTC_3a1e1.dir/testCCompiler.c.o -o cmTC_3a1e1
    /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/lib/libc.a(libc_a-exit.o): in function `exit':
    /build/arm-none-eabi-newlib/src/build-newlib/arm-none-eabi/newlib/../../../newlib-4.3.0.20230120/newlib/libc/stdlib/exit.c:65:(.text.exit+0x28): undefined reference to `_exit'
    /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/lib/libc.a(libc_a-closer.o): in function `_close_r':
    /build/arm-none-eabi-newlib/src/build-newlib/arm-none-eabi/newlib/../../../newlib-4.3.0.20230120/newlib/libc/reent/closer.c:47:(.text._close_r+0x18): undefined reference to `_close'
    /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/lib/libc.a(libc_a-lseekr.o): in function `_lseek_r':
    /build/arm-none-eabi-newlib/src/build-newlib/arm-none-eabi/newlib/../../../newlib-4.3.0.20230120/newlib/libc/reent/lseekr.c:49:(.text._lseek_r+0x24): undefined reference to `_lseek'
    /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/lib/libc.a(libc_a-readr.o): in function `_read_r':
    /build/arm-none-eabi-newlib/src/build-newlib/arm-none-eabi/newlib/../../../newlib-4.3.0.20230120/newlib/libc/reent/readr.c:49:(.text._read_r+0x24): undefined reference to `_read'
    /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/lib/libc.a(libc_a-writer.o): in function `_write_r':
    /build/arm-none-eabi-newlib/src/build-newlib/arm-none-eabi/newlib/../../../newlib-4.3.0.20230120/newlib/libc/reent/writer.c:49:(.text._write_r+0x24): undefined reference to `_write'
    /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/lib/libc.a(libc_a-sbrkr.o): in function `_sbrk_r':
    /build/arm-none-eabi-newlib/src/build-newlib/arm-none-eabi/newlib/../../../newlib-4.3.0.20230120/newlib/libc/reent/sbrkr.c:51:(.text._sbrk_r+0x18): undefined reference to `_sbrk'
    collect2: error: ld returned 1 exit status
    make[1]: *** [CMakeFiles/cmTC_3a1e1.dir/build.make:99: cmTC_3a1e1] Error 1
    make[1]: Leaving directory '/<REDACTED>/wolfBoot/build/CMakeFiles/CMakeScratch/TryCompile-e4htJH'
    make: *** [Makefile:127: cmTC_3a1e1/fast] Error 2

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:43 (project)


-- Configuring incomplete, errors occurred!

I guess cmake doesn't like the multiarch build between the static libs (arm-none-eabi) and the keytools.

Thanks,

make config missing WOLFBOOT_DTS_BOOT_ADDRESS and WOLFBOOT_DTS_UPDATE_ADDRESS

Hi, I encountered a potential problem while building wolfBoot

This occurs if someone uses make config to walk-through setting up the platform, architecture and partition settings.

Problem: Make config doesn’t ask for WOLFBOOT_DTS_BOOT_ADDRESS and WOLFBOOT_DTS_UPDATE_ADDRESS. Problem appears only if there is MMU define in effect for the target architecture.

Compiler:

src/image.c: In function ‘wolfBoot_open_image’:
src/image.c:604:44: error: expected expression before ‘:’ token
  604 |                                            : (void*)WOLFBOOT_DTS_UPDATE_ADDRESS;
      |                                            ^
make: *** [Makefile:166: src/image.o] Error 1

This isn’t a problem if user uses config/examples as a template to wolfBoot root as .config

KeyGenTool Have Some Problem

key_import does not match RSA file import

and RSA2048 KeySize not 320.its 294

image
image
and then another thing,,,,uhmmm. maybe not a question。
image
because i do not use the special section to set this keystore.

[doc] swap space size?

In the document: Targets.md in line 34
Did you mean:

the swap space must be as big as 128KB

instead of:

the swap space must be as big as 64KB

Prevent ext_flash_decrypt_read from writing more data than requested

@Tweakie
Found a potential buffer overflow in wolfBoot.
If row_offset in ext_flash_decrypt_read is different than 0, ext_flash_decrypt_read will write len + ENCRYPT_BLOCK_SIZE - row_offset bytes to the buffer given to ext_flash_decrypt_read. If this buffer has the same size than len, ext_flash_decrypt_read will overwrite the data after this buffer.
I encountered this issue during an encrypted delta upgrade.

Note that ext_flash_decrypt_read will always write at least ENCRYPT_BLOCK_SIZE bytes to the given buffer. If the buffer is smaller than ENCRYPT_BLOCK_SIZE, a buffer overflow will occur.

Created this issue based on #252

Raspberry Pi 3b hardware memory alignment issue

WolfBoot crashes to alignment fault on unaligned access during sha3 calculation on the Raspberry Pi 3b hardware. Running on QEMU Raspberry Pi 3b mode is ok and no alignment exception occurs. Unaligned access occurs in the Wolfcrypt sha3 implementation (sha3.c) at https://github.com/wolfSSL/wolfssl/blob/0d995527aa76a2333b558fcf259145c2646b4c72/wolfcrypt/src/sha3.c#L557

Apparently "AArch64 does permit unaligned data accesses to Normal (not Device) memory with the regular load/store instructions." However in the early stages of the boot all memory is treated as device memory (MMU is not enabled), and this is probably how it should be for the bootloader since the actual payload (like Linux kernel) may expect pristine and clean state to start with. Potentally related background on the armv8 behaviour: https://armv8-ref.codingbelief.com/en/chapter_d4/d42_8_the_effects_of_disabling_a_stage_of_address_translation.html

Following gadget will workaround this issue by using xmemcpy instead of 64-bit load/store when access is not aligned on 8-byte boundary:

--- a/lib/wolfssl/wolfcrypt/src/sha3.c
+++ b/lib/wolfssl/wolfcrypt/src/sha3.c
@@ -554,7 +554,14 @@ static word64 Load64BitBigEndian(const byte* a)
 
     return n;
 #else
-    return *(word64*)a;
+    word64 ret;
+
+    if ((unsigned long) a % 8) {
+        XMEMCPY(&ret, a, sizeof(word64));
+        return ret;
+    }
+
+    return *(const word64*)a;

With that workaround there is a performance hit but no crash and Wolfboot can be used to boot up Linux kernel successfully.

Compilation for cortex-M0

I'm currently trying to use wolfboot as stage 3 bootloader for RP2040.
I made HAL and Linker script.
When i try to compile WolfBoot, i have the following error:
....

[build] Output image(s) successfully created.
[build] lib/wolfssl/wolfcrypt/src/sp_armthumb.c: In function 'sp_256_mul_8':
[build] lib/wolfssl/wolfcrypt/src/sp_armthumb.c:96958:1: error: r7 cannot be used in 'asm' here
[build] 96958 | }
[build] | ^
[build] make[3]: *** [lib/wolfssl/wolfcrypt/src/sp_armthumb.o] Error 1
[build] make[2]: *** [CMakeFiles/wolfboot] Error 2
[build] make[1]: *** [CMakeFiles/wolfboot.dir/all] Error 2

This come from the configuration CORTEX_M0?=1
(because rp2040 has dual-core Cortex-M0+ )
If i remove it (Cortex-M0=0) , it compile correctly.

Am i doing something wrong ?

Support power down protection

Does it support power down protection for image integrity and upgrade process continuously in the case of power down suddently.

i.MX RT10xx operator '*' has no right operand

When compiling for i.MX RT10xx I get the following error

core/devices/MIMXRT1042/MIMXRT1042.h:32067:65: error: operator '*' has no right operand
32067 | #define LPUART1                                  ((LPUART_Type *)LPUART1_BASE)

I've not hit this problem before, as we've been running with a slightly custom wolfBoot version internally.

A solution would be to compare the actual base address as an integer instead of a pointer, i.e. using LPUART1_BASE instead of LPUART1.

Compilation error trying to use Keil uVision ARMCC Compiler

Hello, I´m trying to use WolfBoot in one of my projects. I use Keil uVision 5.27 and the target is STM32F429ZIT6 microcontroller (Nucleo-144 STM32F429 Board). I´m facing the following issue:

Inside boot_arm.c file the function:

void RAMFUNCTION do_boot(const uint32_t *app_offset)
{
    mpu_off();
#ifndef NO_VTOR
    /* Disable interrupts */
    asm volatile("cpsid i");
    /* Update IV */
    VTOR = ((uint32_t)app_offset);
#endif

    /* Get stack pointer, entry point */
    app_end_stack = (*((uint32_t *)(app_offset)));
    app_entry = (void *)(*((uint32_t *)(app_offset + 1)));

    /* Update stack pointer */
    asm volatile("msr msp, %0" ::"r"(app_end_stack));
#ifndef NO_VTOR
    asm volatile("cpsie i");
#endif
    /* Unconditionally jump to app_entry */
    asm volatile("mov pc, %0" ::"r"(app_entry));
}

The compiler issues the following error:

Sources\boot_arm.c(236): error: #18: expected a ")"

this error appears on lines:

asm volatile("msr msp, %0" ::"r"(app_end_stack));
asm volatile("mov pc, %0" ::"r"(app_entry));

Apparently this problem is related to the way of inlining assembly trying to pass some parameter.

Thanks in advance for your help and thanks for sharing this project. Best regards, Yosmany.

IAR linking errors

The functions keystore_get_xxx() definitions are not generated by the keygen.exe tool
I'm just using the generate_key.bat with the following content and it generates the public and private keys as expected but doesn't add these functions:

keytools\keygen.exe --ecc256 ..\src\bootloader\src\ecc256_pub_key.c
move ecc256.der ..\src\bootloader

image

Pointer subtraction might be undefined

I stumbled upon a pointer subtraction:

blksz = end_sha - p;

Is it ok to measure an offset like that? C11 (N1570) states that the behaviour is undefined when not pointing to an array:

6.5.6 Additive operators
....
9 When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

Question: Does wolfBoot builds on windows?

Hi,

I am trying to build wolfBoot on windows, but it is not straight forward. I needed to change makefile to get this going. But now I am failing on python module wolfcrypt. Does wolfcrypt is supported on windows?

`master` does not build with `wolfcrypt` 5.4.0

The master branch does not build with wolfcrypt 5.4.0. Build returns the following error:

Traceback (most recent call last):
  File "/home/cameron/wolfBoot/tools/keytools/sign.py", line 562, in <module>
    ed = ciphers.Ed25519Private(key = wolfboot_key_buffer)
  File "/home/cameron/.local/lib/python3.10/site-packages/wolfcrypt/ciphers.py", line 1233, in __init__
    self.decode_key(key)
  File "/home/cameron/.local/lib/python3.10/site-packages/wolfcrypt/ciphers.py", line 1271, in decode_key
    raise WolfCryptError("Key decode error (%d)" % ret)
wolfcrypt.exceptions.WolfCryptError: Key decode error (-173)

wolfcrypt was installed using pip from PyPI. This error occurred using both the sim and stm32l0 examle configs.

BOOT, UPDATE, SWAP Partitions

Do those partitions have same size ? the design seems to be pretty secure. but it also takes big flash space to realize. is there any optimization on it ?

Content of keystore.der generated by kengen is not correct

The following line in the function "keystore_add" of tools/keytools/keygen.c does not seem to be correct:
fwrite(&sl, sl.pubkey_size, 1, fpub_image);

It should be:
"fwrite(sl.pubkey, sl.pubkey_size, 1, fpub_image);"
or
"fwrite(&sl, sizeof(sl)-KEYSLOT_MAX_PUBKEY_SIZE+sl.pubkey_size, 1, fpub_image);".
Right?

Reset keystore.der

Hi !
I finally got this working and was able to boot.
I tested Wolfboot and i tried to generate new keys (make keysclean make keys). I was not able to boot anymore. I found with debugger that the authenticity check fail right there:

static int keyslot_id_by_sha(const uint8_t *hint)
{
    int id = 0;
    for (id = 0; id < keystore_num_pubkeys(); id++)
    {
        key_hash(id, digest);
        if (memcmp(digest, hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0)
            return id;
    }
    return -1;
}

Because the digest kept the old value (before i regenerate the keystore). Probably i missed something but i can't find anything in documentation.

I really don't know why but i had to modify a lot of Makefile to get working with RP2040. I made a fork if you want add hal/ld for rp2040 but won't work without the stage2 bootloader of pico-sdk. Feel free to contact me if you want more infos.

Core lock up on STM32L0

I am trying to run the test app for the STM32L0 on a Nucleo-L053R8 and am experiencing a core lock up, before the application even gets into the isr_reset function. Any ideas on how to fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.