# IoT Lab 2
In this exercise you will learn how to implement basic crypto operations on constrained resources. We will use the same setup as we did for lab exercise 1. Ubuntu 18.04. (VM) with RIOT-OS and the IoT-Lab. The node is – again – IoT-Lab’s m3-node.
Group members: **<Anna Kastlunger, Gaelle Knibbeler, Judyta Krzyzak>**
RIOT Documentation Link:
https://riot-os.org/api/index.html
## I. IoT-Security WrapUp
Describe the top 5 of the OWASP Top 10 IoT Vulnerabilities thoroughly (in your own words!).
1. Weak Passwords
* Characteristics:
* Simple letter combinations - firstnamelastname, companyname
* Publicly available
* Hardcoded passwords
* Guessable - birthday date, pet's names
* Simple number combinations: 1234, 4321
2. Insecure Network Services
* Many network services that are running are unnecessary (or not required by the user). These are often insecure and require access to the Internet, which means that unauthorized people can access sensitive data. This often also leads to violations of the CIA principles.
3. Insecure Ecosystem Interfaces
* You can imagine that a device is surrounded by several services called the ecosystem. It contains of web API's, backend API's, cloud and mobile interfaces to this system. If one of them is insecure, it can lead to lack of authentication / authorization, weak encryption and / or lack of input and output filtering.
4. Lack of Secure Update Mechanism
* You should be able to securely update your device and its services. A lack of this important feature causes problems like: lack of firmware validation on device, unencrypted transitions which means no secure delivery, lack of anti-rollback mechanisms, and lack of notifications of security changes due to updates.
5. Use of Insecure or Outdated Components
* There is a reason for updates and new components and it is not always to frustrate the user. Attackers pretty easily find ways to hack services and devices therefore the use of deprecated or insecure software components/libraries leads to insecure customization of operating system platforms, and the use of third-party software or hardware components from a compromised supply chain.
## II. Implement basic crypto operations on IoT-Lab’s m3-node
Download the zip files from Moodle:
- lab2_01_shell.zip
- lab2_02_crypto.zip
Move the unzipped directories into your /myRIOT/examples/ directory and follow the steps in
https://tinyurl.com/riotoslab2
### 1) Warm up: shell exercise
#### 1. Edit the file Makefile: add the shell module to the build
USEMODULE += shell

#### 2. Include the header(s) required at the beginning of the main.c file
#include "shell.h"

#### 3. In the main function, the shell can be started by adding the following code before return 0:
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);

#### 4. Now test the application on native:
make
make term


By default, the shell module provides the **help command** to list available commands. Try it. You should see that there is no available command at this stage.

#### 5. In main.c, add the callback functions for the board and cpu commands, just below the line #include "shell.h:
/* board handler */
static int _board_handler(int argc, char **argv)
{
/* These parameters are not used, avoid a warning during build */
(void)argc;
(void)argv;
puts(RIOT_BOARD);
return 0;
}
/* cpu handler */
static int _cpu_handler(int argc, char **argv)
{
/* These parameters are not used, avoid a warning during build */
(void)argc;
(void)argv;
puts(RIOT_CPU);
return 0;
}

#### 6. Define the command name, the help message and the associated callback function in the list of available shell commands.
This is simply done by adding the following code between the function callbacks and the main function:
static const shell_command_t shell_commands[] = {
{ "board", "Print the board name", _board_handler },
{ "cpu", "Print the cpu name", _cpu_handler },
{ NULL, NULL, NULL }
};

#### 7. Test your application on native & on the IoT-Lab testbed
If everything works fine create a new experiment at the IoT-Lab, build your application for the m3 node and upload it to your experiment. Run the experiment - interact with the shell to get the command output. Finally, make screenshots for your documentation.

Use the following command to create a connection to grenoble (to be able to create your own programms on RIOT):
export PATH=$PATH:/home/(your user)/gcc-arm-none-eabi-7-2018-q2-update/bin/
Now you can login to grenoble with ssh
ssh krzyzak@grenoble.iot-lab.info

On RIOT start new experiment with the m3-node



Working on Anna's machine:


Working on Anna's IoT-Lab:

Working on Judyta's IoT-Lab:

---
Damit wir den Exportpfad nicht jedes Mal neu eingeben müssen, schreiben wir ihn in ein Bash-Script:
```nano .bashrc```
```export PATH=$PATH:/home/anna/gcc-arm-none-eabi-7-2018-q2-update/bin/```
Speichern (Strg+X -> y)
Einspielen der Firmware für das Board mit dem wir im IoT-Lab arbeiten in den aktuellen Arbeitsordner:
cd myRIOT/examples/lab2_01_shell
make BOARD=iotlab-m3 all
---
### 2) Crypto Exercise
In this exercise, you will write 2 RIOT shell commands to encrypt and decrypt simple messages. The algorithm will use AES 128 symmetric encryption and more precisely, this exercise will use the CTR cipher mode which is able to encrypt/decrypt messages of arbitrary sizes.
AES encryption is provided by ```crypto``` module of RIOT and CTR cipher mode is provided by the ```cipher_modes``` module.
Document your steps here with screenshots (IoT-Lab) and thorough explanation. Provide a README for your application (don’t forget: no prosa, etc).
### Message encryption/decryption
#### 1. Add required modules to the build
Since the application is about to implement shell functions, the ```shell``` module must be added, as well as the ```fmt```, ```crypto``` and ```cipher_modes``` modules.
Edit the file Makefile and add there the required modules to the build.

#### 2. Add the required includes
Add the inculdes corresponding to the ```fmt```, ```shell``` and ```crypto``` modules that will be used by the application:
#include "shell.h"
#include "fmt.h"
#include "crypto/ciphers.h"
#include "crypto/modes/ctr.h"

#### 3. Define the symmetric key and the nonce:
static const uint8_t key[] = {
0x23, 0xA0, 0x18, 0x53, 0xFA, 0xB3, 0x89, 0x23,
0x65, 0x89, 0x2A, 0xBC, 0x43, 0x99, 0xCC, 0x00
};
static const uint8_t ctr[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};

#### 4. Implement the encrypt command handler function
This function will return the input message in its encrypted form. The encrypted message is printed as a string of hexadecimal characters:
In the ```_encrypt_handler``` function, call the functions that will encrypt the message:
```
cipher_t cipher;
cipher_init(&cipher, CIPHER_AES_128, key, sizeof(key));
size_t enc_len = cipher_encrypt_ctr(&cipher, ctr_copy, 0, (uint8_t *)argv[1], strlen(argv[1]), data);
```

We use a copy of the nonce buffer because it is modifed by the call to ```cypher_encrypt_ctr```.
In the ```_encrypt_handler``` function, convert the encrypted message (a byte array) to its hexadecimal string representation:
```
size_t len = fmt_bytes_hex(buf_str, data, enc_len);
buf_str[len] = 0;
/* The hexadecimal string buffer must be closed to ensure a proper output. */
```

#### 5. Implement the decrypt command handler function:
In the ```_decrypt_handler``` function, you must first convert the hexadecimal representation of the input encrypted message into a byte array:
size_t len = fmt_hex_bytes(data, argv[1]);
Then, decrypt the content of the data buffer:

The output should directly be readable, so there's no need to convert it to hexadecimal.
In the 6th step we should test the application. We did not do it, since it would be necessary to uncomment the rest of the code which is a lot of work. Now, by entering 'make' we are getting a series of errors.

We checked the errors and realized they were only about the parts of code that we didn't write yet, e.g.:

We can say that there are no errors in the lines we have already written, since the compiler checks the file chronologically.
### Sign & Verify Messages
---
In this exercise, you will write RIOT shell commands to sign and verify simple messages:
* One command that signs and prints the signature
* One command that verifies the signature
* One command to generate the key pair used to sign/verify the message
#### 1. Add required modules
Add the module ```random``` and the external package ```c25519``` to your Makefile

#### 2. Add the corresponding includes to the main.c file
For the ```c25519``` you will need an additional header file: ```edsign.h``` besides the common header file.

#### 3. Implement the key command handler function that will generate a new pair of key each time it is called
First, under the header includes, declare 2 buffers where the asymmetric keys are stored:
static uint8_t secret_key[EDSIGN_SECRET_KEY_SIZE] = { 0 };
static uint8_t public_key[EDSIGN_PUBLIC_KEY_SIZE] = { 0 };

In the ```_key_handler``` function, call the functions that will create the new keypair:
random_bytes(secret_key, sizeof(secret_key));
ed25519_prepare(secret_key);
/* implement the derivation of the public_key here */

Then print the new keypair:
```
puts("New keypair generated:");
printf(" - Secret: ");
for (uint8_t i = 0; i < EDSIGN_SECRET_KEY_SIZE; ++i)
{
printf("%02X", secret_key[i]);
}
printf("\n - Public: ");
for (uint8_t i = 0; i < EDSIGN_PUBLIC_KEY_SIZE; ++i)
{
printf("%02X", public_key[i]);
}
puts("");
```

#### 4. Implement the sign command handler function that will generate a signature from an input message:
First, under the header includes, declare 2 buffers where the signatures (byte and hex representation) are stored:
static uint8_t signature[EDSIGN_SIGNATURE_SIZE] = { 0 };
static char signature_hex[EDSIGN_SIGNATURE_SIZE * 2 + 1] = { 0 };

**Note**: the size of the hexadecimal string signature buffer is twice as large as the signature buffer itself, because a single byte is represented by 2 hexadecimal characters.
In the ```_sign_handler``` function, call the functions that will generate the signature of the input command argument message in argv[1]:
edsign_sign(signature, public_key, secret_key, (uint8_t *)argv[1], strlen(argv[1]));

Implement the conversion of the signature (a byte array) to its hexadecimal string representation:
signature to signature_hex

#### 5. Implement the verify command handler function
The message and the signature are provided as command line argument respectively in ```argv[1]``` and ```argv[2]```.
In the ```_verify_handler``` function, you must first convert the signature provided as a string of hex characters to a byte array, this is done with the ```hex_bytes``` function (from the fmt module):
fmt_hex_bytes(signature, argv[2]);

Then call the functions that verify the signature:
```
if (edsign_verify(signature, public_key, (uint8_t *)argv[1], strlen(argv[1])))
{
puts("Message verified");
}
else
{
puts("Message not verified");
}
```

#### 6. Test your application
If everything works fine create got to next section "Hash Computation".
Not really:

But we continue anyway.
----
### 3) Hash Computation
In this exercise, you will write RIOT shell commands to compute the hash of a given input string:
* One command that produces and prints the hash using the SHA256 algorithm
* One command that produces and prints the hash using the SHA3-256 algorithm
In both cases, the hash is stored in memory in a byte array and, to print it, it must be converted to a string of hexadecimal characters. Use an appropriate module for the conversion.
Hash functions of several algorithms (SHA256, SHA3-256, SHA1, MD5, CMAC) are provided by the ```hashes``` module.
#### 1. Add required modules
Add the ```hashes``` module.

#### 2. Add the corresponding header files
Hint: You will need the header files for sha256 and sha3.

#### 3. Implement the sha256 command handler function:
Declare 2 buffers, the first one for the computed hash itself, and the second one for its hexadecimal string representation:
static uint8_t sha256_hash[SHA256_DIGEST_LENGTH];
static char sha256_hash_hex[SHA256_DIGEST_LENGTH * 2 + 1];

Note: the size of the hexadecimal string buffer is twice as large as the hash itself, because a single byte is represented by 2 hexadecimal characters.
In the ```_sha256_handler``` function call the functions that will compute the hash from the command line argument ```argv[1]```:
implement the functions to compute a sha256 hash of a string (argv[1])

Convert the computed hash (a byte array) to its hexadecimal string representation:
you know what to use by now ;) (sha256_hash to sha256_hash_hex)

#### 4. Implement the sha3 command handler function
Declare 2 buffers, the first one for the computed hash itself, and the second one for its hexadecimal string representation:
static uint8_t sha3_hash[SHA3_256_DIGEST_LENGTH];
static char sha3_hash_hex[SHA3_256_DIGEST_LENGTH * 2 + 1];

Call the functions that will compute the hash from the command line argument ```argv[1]```:
implement the functions to compute a sha256 hash of a string (argv[1])

Convert the computed hash (a byte array) to its hexadecimal string representation:

Since we are programming in C and don't like to see something like:

we need to THINK and declare the functions in the last step:

#### 5. Test your application on native & on the IoT-Lab testbed
If everything works fine **create a new experiment at the IoT-Lab**, build your application for the m3 node and upload it to your experiment. Run the experiment - interact with the shell to get the command output. Finally, make screenshots for your documentation.

Enter 'make'

Make term and trying out the functions:

It works!
On native:


And on the IoT-Server:


And another IoT-Server:

## III. Upload to Moodle
Submit 1 zip file for the crypto exercise containing your app’s main.c, Makefile, and README.