# OpenSSL

OpenSSL is a library for general-purpose cryptography. OpenSSL is also an open-source command line tool that is commonly used to generate private keys, create CSRs, install your SSL/TLS certificate, and identify certificate information.

## Build + Install

{% code overflow="wrap" %}

```bash
#!/bin/bash -xe

#For X86
export ARCH=""
export CROSS_COMPILE=""
export OPENSSL_TARGET=""

#For arm64, source toolchain and set the below config
<<ARM64
export ARCH=arm64
export CROSS_COMPILE="aarch64-linux-gnu-"
export OPENSSL_TARGET=linux-aarch64
ARM64

echo "Download OpenSSL 1.1.1g"
wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz

echo "untaring... openSSL"
tar -xf  openssl-1.1.1g.tar.gz
cd openssl-1.1.1g

echo "Configuring OpenSSL"
./Configure ${OPENSSL_TARGET} shared -pg -fPIC --cross-compile-prefix=$CROSS_COMPILE --prefix=/tmp/openssl11 --openssldir=/tmp/openssl11/etc/ssl

echo "Building ..."
make -j8

echo "Installing ...."
make install_sw DESTDIR=<path to staging dir>
```

{% endcode %}

Successful compilation directs output into 3 directories

```bash
Ubuntu@staging/tmp/openssl11
❯ tree 2
.
├── bin
│   ├── c_rehash
│   └── openssl
├── include
│   └── openssl
└── lib
    ├── engines-1.1
    ├── libcrypto.a
    ├── libcrypto.so -> libcrypto.so.1.1
    ├── libcrypto.so.1.1
    ├── libssl.a
    ├── libssl.so -> libssl.so.1.1
    ├── libssl.so.1.1
    └── pkgconfig

```

```bash
export LD_LIBRARY_PATH=<path till lib dir>
./bin/openssl version -a
```

## Commands

These commands are for "secp384r1" curve. The same applies to other supported curves.

```bash
# check the version of openssl
openssl version -a

# Get a random number
openssl rand -hex 64

# Generate Private key for secp384 curve
openssl ecparam -genkey -name secp384r1 -out privatekey.pem

# Generate Certificate for a given private key 
openssl req -new -sha256 -key privatekey.pem -out csr.csr -subj "/C=US/ST=FL/L=Orlando/O=Foo LLC/OU=IT/CN=www.example.com"

# Generate Public key for given private key and certificate.
openssl req -x509 -sha256 -days 365 -key privatekey.pem -in csr.csr -out publickey.pem

# Start server instance on port 8443
openssl s_server -tls1_3 -accept 8443 -cert publickey.pem -curves secp384r1 -key privatekey.pem

# Connect to the server with the client
openssl s_client -tls1_3 -curves secp384r1 -connect <server_ip>:8443 
```

> * -engine \<engine name>  : Accelarate with specified engine
> * -tls1\_3 : Use TLSv1.3 for communication
> * -quiet: less verbose&#x20;
> * -rand \<path to node > : use the specified random number from node instead of kernel entrophy&#x20;

## API's

#### Leverage custom engine

OpenSSL provides flexibility to offload operations onto custom HW.  The below code leverages the engine to perform all OpenSSL operations

<pre class="language-c"><code class="lang-c">ENGINE_load_builtin_engines();
<strong>ENGINE *e = ENGINE_by_id("engine name");
</strong>// Make the engine's implementations the default implementations
ENGINE_init(e)
ENGINE_set_default_digests(e)
// Set default engine
ENGINE_set_default(e, ENGINE_METHOD_ALL);
// Free the engine
ENGINE_free(e);
ENGINE_cleanup();
</code></pre>

#### Load custom Random numbers

```c
// seed PRNG
if (RAND_load_file("/dev/<node>", 256) < 64) {
      printf("Can't seed PRNG!\n");
      return -1;
}
```

#### Allocate, Initialize and Generate key pair

```c
// Allocates memory for key pair
EC_KEY *eckey=EC_KEY_new();
// Assign curve to the keypair
EC_GROUP *ecgroup= EC_GROUP_new_by_curve_name(NID_secp384r1);
// Map the keypair and curve
set_group_status = EC_KEY_set_group(eckey,ecgroup);
// Generate key pair, it will offload to engine,
// performs 2 PM operations.
gen_status = EC_KEY_generate_key(eckey);

//Free the handlers
EC_GROUP_free(ecgroup);
EC_KEY_free(eckey);
```

#### Sign Key

```c
// Sign the key with given hash
ECDSA_SIG *signature;
signature = ECDSA_do_sign(hash, strlen(hash), eckey);

// Free Signature
ECDSA_SIG_free(signature);
```

#### Verify Signed Key

```c
// Verify Signature
verify_status = ECDSA_do_verify(hash, strlen(hash), signature, eckey);
```

#### Point Multiplication

```c
// Perform point multiplication
ret = EC_POINT_mul(ecgroup, pub_key, privKeyBN, NULL, NULL, ctx);
```

## Engine

OpenSSL provides flexibility to offload operations onto custom HW.\
**openssl** command searches for the custom engine library (so) in

* default : **`/usr/lib/engines-1.1/`**
* OpenSSL : **`<path to openssl>/lib/engines-1.1/`**&#x20;

{% code title="Check Custom Engine" %}

```
openssl engine <engine name>
```

{% endcode %}

{% hint style="info" %}
-engine \<engine name>&#x20;
{% endhint %}

## Benchmarking

```bash
# Benchmark all curves ecdsa operations
openssl speed -elapsed ecdsa

# Benchmark single curve ecdsa operations
openssl speed -elapsed ecdsap384

# Benchmark all curves point multiplication
openssl speed -elapsed ecdh

# Benchmark single curve point multiplication
openssl speed -elapsed ecdhp384
```

> * -elapsed gives wall clock time ( actual time lapse ).\
>   &#x20;Without elapsed it measures only active CPU time.
> * -multi \<n> : runs on multiple instances on multiple cores. &#x20;
