Commit cd953819 authored by obronchain's avatar obronchain

initial commit

parents
# MIT Licence
#
# Copyright 2020 UCLouvain
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the Software
# is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#######################
###### USER SETTINGS
#######################
# 1 for protected implementation
MASKING=1
# Number of shares within the implementation
D=8
########################
###### directories
########################
BOARD_DIR=board_m0/
BOARD_DIR_INV=../
OPENOCD_DIR=/usr/local/share/openocd
BDIR?=build
SRCDIR_SPOOK_MASKED?=embedded_src/spook_masked
SRCDIR_SPOOK_REF?=embedded_src/spook_ref
########################
###### Additional flags
########################
# 1 for ASM implementation, C otherwise
USE_ASM=1
# 1 to turn on PRNG
PRGON=1
# only run for round for encryption and decryption in clyde
# this makes the target non functional but allows to reduce measurement
# time. Does not change the content of the traces.
ROUNDREDUCED=0
########################
###### Compiler Flag
########################
DEBUG=0
OPT=-Os
CC = arm-none-eabi-gcc
AR = arm-none-eabi-ar
CPU=-mcpu=cortex-m0
CFLAGS += -fdata-sections -ffunction-sections -mthumb-interwork -mthumb $(CPU) -fPIC -std=c99
CFLAGS += $(OPT)
########################
###### Compiler Flag
########################
ifeq ($(USE_ASM),1)
CFLAGS += -DUSE_ASM
endif
ifeq ($(ROUNDREDUCED),1)
CFLAGS += -DROUNDREDUCED
endif
ifeq ($(MASKING),0)
D=1
endif
all: libspook
clean:
make -C $(BOARD_DIR) clean
rm $(BDIR) -rf
bdir:
mkdir -p $(BDIR)
.PHONY: clean bdir
##############
#SPOOK MASKED
##############
LIBSPOOK_MASKED= $(BDIR)/libspook_masked.a
objects_spook_masked += prng.o
ifeq ($(MASKING),1)
objects_spook_masked += clyde_masked.o utils_masking.o
CFLAGS += -DMASKING -DD=$(D) -DPRGON=$(PRGON) -DINVERSE
ifeq ($(USE_ASM),1)
objects_spook_masked += utils_masking_asm.o
endif
endif
$(BDIR)/%.o: $(SRCDIR_SPOOK_MASKED)/%.c bdir
$(CC) -c -o $@ $< $(CFLAGS) -I $(SRCDIR_SPOOK_MASKED) -I $(SRCDIR_SPOOK_REF)
$(BDIR)/%.o: $(SRCDIR_SPOOK_MASKED)/%.S bdir
$(CC) -c -o $@ $< $(CFLAGS) -I $(SRCDIR_SPOOK_MASKED) -I $(SRCDIR_SPOOK_REF)
libspook_masked: $(patsubst %,$(BDIR)/%,$(objects_spook_masked)) bdir
$(AR) cr $(LIBSPOOK_MASKED) $(patsubst %,$(BDIR)/%,$(objects_spook_masked))
echo "Done libspook_masked"
##############
# SPOOK REF
##############
objects_spook_ref := s1p.o encrypt.o primitives.o shadow_32bit.o
ifeq ($(MASKING),0)
# unprotected clyde is needed if no masking is used
objects_spook_ref += clyde_32bit.o
endif
$(BDIR)/%.o: $(SRCDIR_SPOOK_REF)/%.c bdir
$(CC) -c -o $@ $< $(CFLAGS) -I $(SRCDIR_SPOOK_REF)
libspook_ref: $(patsubst %,$(BDIR)/%,$(objects_spook_ref))
echo "Done libspook_ref lib"
###################
# Complete libspook
###################
LIBSPOOK=$(BDIR)/libspook.a
libspook: libspook_masked libspook_ref
$(AR) cr $(LIBSPOOK) $(patsubst %,$(BDIR)/%,$(objects_spook_ref)) $(patsubst %,$(BDIR)/%,$(objects_spook_masked))
##############
# board
##############
HEXFILE=board/build/stm32_f0.hex
board: libspook
@echo "Compiling for board"
@echo $(C_INCLUDES_EXT)
make -C $(BOARD_DIR) clean
make -C $(BOARD_DIR) DEBUG=$(DEBUG) LIBSPOOK=$(BOARD_DIR_INV)/$(LIBSPOOK) D=$(D) MASKING=$(MASKING) USE_ASM=$(USE_ASM) CPU=$(CPU)
echo "# !!!! Autogenerated in Makefile" > interface/parameters.py
echo "D = $(D)" >> interface/parameters.py
echo "PRGON = $(PRGON)" >> interface/parameters.py
burn:
/usr/local/bin/openocd -f board_m0/stm32_f0.cfg -c "program board_m0/build/stm32_f0.elf verify reset exit"
##############
# test script
##############
test_board: clean board burn
python3 tests/test_board.py
Spook SW CTF
This work has been developped at UCLouvain.
Unless noted otherwise subsequently or in individual files, the files are copyright UCLouvain.
Unless noted otherwise subsequently or in the files in question the
following licenses apply:
-All files in the "board_m0" directory and its subdirectories are
licensed under the BSD 3-Clause licence. You may obtain a copy of
the Licence at opensource.org/licenses/BSD-3-Clause
-All files in the "capture", "interface" and "tests" directories and
their subdirectories and the "Makefile" are
licensed under the MIT License as defined at the beginning of each file.
-All files in the "embedded_src" directory and its subdirectories are
licenced under the Apache 2.0 licence as defined in the "embedded_src/LICENCE" file.
You may obtain a copy of the Licence at http://www.apache.org/licenses/LICENSE-2.0
-The "README.md" and "SETUP.md" file are licensed
under the Creative Commons Attribution 4.0 International License, as defined
in https://creativecommons.org/licenses/by/4.0/legalcode.
# **Spook Software Capture the Flag (CTF)**
This project contains all the sources for the Software Capture the Flag on a [STM32 F0 Cortex-M0 Discovery board](https://www.st.com/en/evaluation-tools/32f0308discovery.html). This CTF makes available datasets for current measurement on (Spook)[https://spook.dev].
_Note: no security claims comes with this code. It is a straightfoward implementation of state-of-the-art software masking scheme of which security depends on various factors such as effective masking order and noise level which are not guaranteed with this code._
## Directory description
This project contains several directories:
* [embedded_src/](embedded_src): contains Spook authenticated encryption source code. There, [spook_ref/](embedded_src/spook_ref) contains the complete Spook mode of operation while [spook_masked/](embedded_src/spook_masked) contains the masked Clyde implementation.
* [interface/](interface/): contains Python scripts to interact with the target. The file [spook_masked.py](interface/spook_masked.py) allows to run the masked implementation of Spook. It can be used to retrieve all the intermediates variables within an execution (i.e. for profiled attacks). [parameters.py](interface/parameters.py) contains the parameters of the implementation such as the number of shares.
* [capture/](capture/): contains the scripts used to generate the datasets.
* [board_m0/](board/): stores the system files used by the target. It has been mostly generated by [STM32CubeMX](https://www.st.com/en/development-tools/stm32cubemx.html).
* [test/](test/): contains functional testing scripts.
## Rational for masked implementation
In order to secure Spook against side-channel long term key recovery attacks, only calls to the tweakable blockcipher Clyde have to be protected. Next, we give a few technical details and refer to the code itself for further details.
* Clyde is bitslice oriented operating on 32-bit words. This makes natural the use of the [Goudarzi and Rivain masking scheme](https://eprint.iacr.org/2016/264.pdf). It is based on [ISW](https://link.springer.com/chapter/10.1007/978-3-540-45146-4_27) multiplication for non-linear operation and SNI refreshing. Linear operations are performed share-wise.
* Overall, a sharing of a 32-bit word with D shares is an array of D consecutive words in memory. In order to unmask that word, all the D elements of the array are bitwise XORed together. A Clyde state (4 times 32-bit), is then an array of size 4*D.
* It is expected to be t-probing secure since SNI refreshes have been inserted according to recent tool Tornado.
* Operations on the shares are implemented in Assembly while control logic is in C language. For readability, the project also contains C functions equivalent to the Assembly ones but are not used for this CTF.
* Assembly is not tuned for performances but to reduce lower order leakages. As a consequence, these are reduced but still exist.
## Data-sets
For the challenge, various data-sets are available for each number of shares. Namely, 200k traces with random key and random nonce are available in `random_key/`. These are typically used profiling. Five different sets with a fixed key of 100k traces are also available in `fixed_key/key_X/`. They can be used for challengers to evaluate their attacks. Evaluation of the submitted attacks will be performed on similar secret traces with fixed secret key. All the data-set are split in multiple files containing each 10k traces.
### Traces description
The avaible traces are raw current traces recorded with a [CT1 current probe](https://download.tek.com/datasheet/AC_Current_Probes.pdf) placed between the power regulator and the target (see [SETUP.md](SETUP.md) for more details). Only the first sbox and lbox layers are recorded within the traces as depicted in the following example (D=4). There, one can observe the first step of Clyde which includes the sbox with 4 ISW multiplications and one refresh. After the sbox layer comes the lbox.
![traces_d4](.figs/traces_d4.png)
### File format
The traces are stored in a [.npz](https://imageio.readthedocs.io/en/stable/format_npz.html) format with various fields:
* **traces**: is a int16 matrix where each of the nt rows is a trace corresponding to an encryption. Each file contains nt=10k traces.
* **nonces**: is a (nt,4) uint32 matrix where each row is the nonce used for the corresponding encryption.
* **umsk_keys**: is a (nt,4) uint32 matrix where each row is the secret key.
* **msk_keys**: is a (nt,4*D) uint32 matrix where each row is the D sharing of the secret key used. The shares are layout as described above.
* **seeds**: is a (nt,4) uint32 matrix where each row is a 128-bit word used to seed the prng.
* **ad**: is the associated data. It is fixed to zero since it has no impact on the first Clyde call.
* **m**:is the message. It is fixed to zero since it has no impact on the first Clyde call.
Based on this data and [spook_masked.py](interface/spook_masked.py), one can recover the intermediate masked states for each of the traces. As an example, to recover the state after the first lbox layer can be obtained by running
```
msk_state = clyde128_encrypt_masked(nonces.T,np.zeros((4,nt),dtype=np.uint32),msk_key.T,seeds.T,Nr=1,step=0)
```
### Pseudo-Random Number Generation
The randomness used by the masked implementation is generated from the Shadow-512 permutation in sponge mode (see [prng.c](embedded_src/spook_masked/prng.c)). Precisely, a 128-bit seed initializes a Shadow state. Then, this state is updated by running Shadow-512. The 256-bit of capacity are the pseudo random numbers and the state is updated again. This permutation is used since it is already required by Spook.
Practically, the randomness is precomputed and stored in memory. This excludes their generation from recorded traces to reduce their length.
This file and all the figures used are licensed under a [Creative Commons Attribution 4.0 International
License][cc-by].
[![CC BY 4.0][cc-by-image]][cc-by]
[cc-by]: http://creativecommons.org/licenses/by/4.0/
[cc-by-image]: https://i.creativecommons.org/l/by/4.0/88x31.png
[cc-by-shield]: https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg
# Reproduce the measurement setup
## Hardware requirements
In order to use a low-cost platform, we have decided to use a STMicroelectronics Discovery board. The version used for this ctf is based on the [STM32F030R8](https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-mainstream-mcus/stm32f0-series/stm32f0x0-value-line/stm32f030r8.html) with an ARM Cortex-M0. The configuration we have adopted is the _HSE oscillator on-board from X2 crystal (not provided)_, reported at page 17 of the [user manual of the board](https://www.st.com/resource/en/user_manual/dm00092306-discovery-kit-for-stm32f030-value-line-microcontrollers-stmicroelectronics.pdf). The list of modifications we have applied to the board are listed as follows:
* In X2, a 8MHz quartz [crystal](https://be.farnell.com/txc/9b-8-000maaj-b/xtal-8-000mhz-18pf-hc-49s/dp/1842268?ost=crystal+9B-8.000MAAJ-B) has been soldered. We have used a through-hole type component. Following the user manual and the schematic, we have used a 18pF capacitors for C13 and C14. The resistor R23 is zero ohm and R22 is 390 ohms. In addition, we have removed solder bridges SB16, SB17 and SB18.
* To increase the available bandwidth at the probing point, we have removed C18, C19, C20, C21. In addition, L1 has been substituted with a 0ohm resistor.
Once these modifications are done, one can plug the board in the following way:
1. **UART**: The board and the computer communicates through an external UART interface. Namely, an [UM232R](https://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_UM232R.pdf) is connected to the board with TX and RX being respectively PA9 and P10. On this point, any other UART modules will work.
2. **Clock**: The device is clocked at its maximum frequency of 48MHz.
3. **Trigger**: Before each encryption or decryption of Spook, the pin PB13 is set high. Afterwards, the pin is set to low. Hence, an oscilloscope should be triggered on the a rising edge of this signal.
4. **Probe**: The probe we have used is a CT1 that is placed on the second jumper (JP2).
To run the project, several packages have to be installed. The following instructions are dedicated to Ubuntu but could be transposed to other linux distributions:
```
sudo pip install pyserial numpy
```
The ARM tool chain is installed following [this link](https://blog.podkalicki.com/how-to-compile-and-burn-the-code-to-stm32-chip-on-linux-ubuntu/). In short, it requires to run:
```
sudo apt-get install gcc-arm-none-eabi binutils-arm-none-eabi
```
and the device is flashed and debugged with openocd:
```
sudo apt-get install openocd
```
### Parameters
The crypto library can be compiled with many options. Next, several compilation flags are detailed.
1. `MASKING=1` means the masking is implemented. In this case, the inverse of clyde is also used for decryption. Please refer to [Spook website](https://spook.dev/) for more details.
2. `D=X` is the number of shares. It is used only if `MASKING` is set to 1.
3. `USE_ASM=1` is set if the shares are manipulated using assembly code. The project contains C and ASM code for many critical functions in utils_masking_asm.S. This flag makes use of the ASM version.
4. `BOARD=1` builds all the operating system used by the board. It generates a .elf that can be burn to the chip.
5. `DEBUG=1` debug mode is set.
As an example, to flash the board with masked implementation with 4 shares and assembly code, the following command is used:
```
make D=4 USE_ASM=1 BOARD=1 board burn
```
This generates the file [parameters.py](interface/parameters.py). It will later be used by the interface (i.e. to recover the number of shares).
### Functional Testing Scripts
The project contains testing scripts for the primary candidate of Spook. These are checking that the ciphertext matches the test vectors coming with the reference implementation of Spook. It also verifies the consistency of the decryption.
The on-board tests can be launched thanks to
```
make BOARD=1 test_board
```
where all the previously mentioned flags can be used. This will launch scripts within [test/](test/)
### Measurement Scripts
An example using a Picoscope is available in [capture.py](capture/capture.py). It provides the MCU with a masked key and additional inputs. Internally, the device will run a batch of encryptions with fresh inputs. The capture scripts derives these inputs with the function dev.unroll(N) and store then in a trace file. Then a simulation of the chip is available in [spook_masked.py](interface/spook_masked.py). As an example, one can run
```
python3 capture.py -b 1000 -n 4000 -k 1
```
This will capture 4000 traces where a batch of 1000 traces are recorded at once with a fixed key (-k 1).
This file and all the figures used are licensed under a [Creative Commons Attribution 4.0 International
License][cc-by].
[![CC BY 4.0][cc-by-image]][cc-by]
[cc-by]: http://creativecommons.org/licenses/by/4.0/
[cc-by-image]: https://i.creativecommons.org/l/by/4.0/88x31.png
[cc-by-shield]: https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg
/* ----------------------------------------------------------------------
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* $Date: 17. January 2013
* $Revision: V1.4.0
*
* Project: CMSIS DSP Library
* Title: arm_class_marks_example_f32.c
*
* Description: Example code to calculate Minimum, Maximum
* Mean, std and variance of marks obtained in a class
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of ARM LIMITED nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* -------------------------------------------------------------------- */
/**
* @ingroup groupExamples
*/
/**
* @defgroup ClassMarks Class Marks Example
*
* \par Description:
* \par
* Demonstrates the use the Maximum, Minimum, Mean, Standard Deviation, Variance
* and Matrix functions to calculate statistical values of marks obtained in a class.
*
* \note This example also demonstrates the usage of static initialization.
*
* \par Variables Description:
* \par
* \li \c testMarks_f32 points to the marks scored by 20 students in 4 subjects
* \li \c max_marks Maximum of all marks
* \li \c min_marks Minimum of all marks
* \li \c mean Mean of all marks
* \li \c var Variance of the marks
* \li \c std Standard deviation of the marks
* \li \c numStudents Total number of students in the class
*
* \par CMSIS DSP Software Library Functions Used:
* \par
* - arm_mat_init_f32()
* - arm_mat_mult_f32()
* - arm_max_f32()
* - arm_min_f32()
* - arm_mean_f32()
* - arm_std_f32()
* - arm_var_f32()
*
* <b> Refer </b>
* \link arm_class_marks_example_f32.c \endlink
*
*/
/** \example arm_class_marks_example_f32.c
*/
#include "arm_math.h"
#define USE_STATIC_INIT
/* ----------------------------------------------------------------------
** Global defines
** ------------------------------------------------------------------- */
#define TEST_LENGTH_SAMPLES (20*4)
/* ----------------------------------------------------------------------
** List of Marks scored by 20 students for 4 subjects
** ------------------------------------------------------------------- */
const float32_t testMarks_f32[TEST_LENGTH_SAMPLES] =
{
42.000000, 37.000000, 81.000000, 28.000000,
83.000000, 72.000000, 36.000000, 38.000000,
32.000000, 51.000000, 63.000000, 64.000000,
97.000000, 82.000000, 95.000000, 90.000000,
66.000000, 51.000000, 54.000000, 42.000000,
67.000000, 56.000000, 45.000000, 57.000000,
67.000000, 69.000000, 35.000000, 52.000000,
29.000000, 81.000000, 58.000000, 47.000000,
38.000000, 76.000000, 100.000000, 29.000000,
33.000000, 47.000000, 29.000000, 50.000000,