1# Lws Crypto Apis
2
3## Overview
4
5![lws crypto overview](/doc-assets/lws-crypto-overview.svg)
6
7Lws provides a "generic" crypto layer on top of both OpenSSL and
8compatible tls library, and mbedtls.  Using this layer, your code
9can work without any changes on both types of tls library crypto
10backends... it's as simple as rebuilding lws with `-DLWS_WITH_MBEDTLS=0`
11or `=1` at cmake.
12
13The generic layer can be used directly (as in, eg, the sshd plugin),
14or via another layer on top, which processes JOSE JSON objects using
15JWS (JSON Web Signatures), JWK (JSON Web Keys), and JWE (JSON Web
16Encryption).
17
18The `JW` apis use the generic apis (`lws_genrsa_`, etc) to get the crypto tasks
19done, so anything they can do you can also get done using the generic apis.
20The main difference is that with the generic apis, you must instantiate the
21correct types and use type-specfic apis.  With the `JW` apis, there is only
22one interface for all operations, with the details hidden in the api and
23controlled by the JSON objects.
24
25Because of this, the `JW` apis are often preferred because they give you
26"crypto agility" cheaply... to change your crypto to another supported algorithm
27once it's working, you literally just change your JSON defining the keys and
28JWE or JWS algorithm.  (It's up to you to define your policy for which
29combinations are acceptable by querying the parsed JW structs).
30
31## Crypto supported in generic layer
32
33### Generic Hash
34
35 - SHA1
36 - SHA256
37 - SHA384
38 - SHA512
39
40### Generic HMAC
41
42 - SHA256
43 - SHA384
44 - SHA512
45
46### Generic AES
47
48 - CBC
49 - CFB128
50 - CFB8
51 - CTR
52 - ECB
53 - OFB
54 - XTS
55 - GCM
56 - KW (Key Wrap)
57
58### Generic RSA
59
60 - PKCS 1.5
61 - OAEP / PSS
62
63### Generic EC
64
65 - ECDH
66 - ECDSA
67 - P256 / P384 / P521 (sic) curves
68
69## Using the generic layer
70
71All the necessary includes are part of `libwebsockets.h`.
72
73Enable `-DLWS_WITH_GENCRYPTO=1` at cmake.
74
75|api|header|Functionality|
76|---|---|---|
77|genhash|[./include/libwebsockets/lws-genhash.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genhash.h)|Provides SHA1 + SHA2 hashes and hmac|
78|genrsa|[./include/libwebsockets/lws-genrsa.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genrsa.h)|Provides RSA encryption, decryption, signing, verification, key generation and creation|
79|genaes|[./include/libwebsockets/lws-genaes.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genaes.h)|Provides AES in all common variants for encryption and decryption|
80|genec|[./include/libwebsockets/lws-genec.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-genec.h)|Provides Elliptic Curve for encryption, decryption, signing, verification, key generation and creation|
81|x509|[./include/libwebsockets/lws-x509.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-x509.h)|Apis for X.509 Certificate loading, parsing, and stack verification, plus JWK key extraction from PEM X.509 certificate / private key|
82
83Unit tests for these apis, which serve as usage examples, can be found in [./minimal-examples/api-tests/api-test-gencrypto](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-gencrypto)
84
85### Keys in the generic layer
86
87The necessary types and defines are brought in by `libwebsockets.h`.
88
89Keys are represented only by an array of `struct lws_jwk_elements`... the
90length of the array is defined by the cipher... it's one of
91
92|key elements count|definition|
93|---|---|
94|`LWS_COUNT_OCT_KEY_ELEMENTS`|1|
95|`LWS_COUNT_RSA_KEY_ELEMENTS`|8|
96|`LWS_COUNT_EC_KEY_ELEMENTS`|4|
97|`LWS_COUNT_AES_KEY_ELEMENTS`|1|
98
99`struct lws_jwk_elements` is a simple pointer / length combination used to
100store arbitrary octets that make up the key element's binary representation.
101
102## Using the JOSE layer
103
104The JOSE (JWK / JWS / JWE) stuff is a crypto-agile JSON-based layer
105that uses the gencrypto support underneath.
106
107"Crypto Agility" means the JSON structs include information about the
108algorithms and ciphers used in that particular object, making it easy to
109upgrade system crypto strength or cycle keys over time while supporting a
110transitional period where the old and new keys or algorithms + ciphers
111are also valid.
112
113Uniquely lws generic support means the JOSE stuff also has "tls library
114agility", code written to the lws generic or JOSE apis is completely unchanged
115even if the underlying tls library changes between OpenSSL and mbedtls, meaning
116sharing code between server and client sides is painless.
117
118All the necessary includes are part of `libwebsockets.h`.
119
120Enable `-DLWS_WITH_JOSE=1` at CMake.
121
122|api|header|Functionality|
123|---|---|---|
124|JOSE|[./include/libwebsockets/lws-jose.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jose.h)|Provides crypto agility for JWS / JWE|
125|JWE|[./include/libwebsockets/lws-jwe.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jwe.h)|Provides Encryption and Decryption services for RFC7516 JWE JSON|
126|JWS|[./include/libwebsockets/lws-jws.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jws.h)|Provides signature and verifcation services for RFC7515 JWS JSON|
127|JWK|[./include/libwebsockets/lws-jwk.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-jwk.h)|Provides signature and verifcation services for RFC7517 JWK JSON, both "keys" arrays and singletons|
128
129Minimal examples are provided in the form of commandline tools for JWK / JWS / JWE / x509 handling:
130
131 - [JWK minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-jwk)
132 - [JWS minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-jws)
133 - [JWE minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-jwe)
134 - [X509 minimal example](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/crypto/minimal-crypto-x509)
135
136Unit tests for these apis, which serve as usage examples, can be found in [./minimal-examples/api-tests/api-test-jose](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/api-tests/api-test-jose)
137
138## Crypto supported in the JOSE layer
139
140The JOSE RFCs define specific short names for different algorithms
141
142### JWS
143
144|JSOE name|Hash|Signature|
145---|---|---
146|RS256, RS384, RS512|SHA256/384/512|RSA
147|ES256, ES384, ES521|SHA256/384/512|EC
148
149### JWE
150
151|Key Encryption|Payload authentication + crypt|
152|---|---|
153|`RSAES-PKCS1-v1.5` 2048b & 4096b|`AES_128_CBC_HMAC_SHA_256`|
154|`RSAES-PKCS1-v1.5` 2048b|`AES_192_CBC_HMAC_SHA_384`|
155|`RSAES-PKCS1-v1.5` 2048b|`AES_256_CBC_HMAC_SHA_512`|
156|`RSAES-OAEP`|`AES_256_GCM`|
157|`AES128KW`, `AES192KW`, `AES256KW`|`AES_128_CBC_HMAC_SHA_256`|
158|`AES128KW`, `AES192KW`, `AES256KW`|`AES_192_CBC_HMAC_SHA_384`|
159|`AES128KW`, `AES192KW`, `AES256KW`|`AES_256_CBC_HMAC_SHA_512`|
160|`ECDH-ES` (P-256/384/521 key)|`AES_128/192/256_GCM`|
161|`ECDH-ES+A128/192/256KW` (P-256/384/521 key)|`AES_128/192/256_GCM`|
162
163### Keys in the JOSE layer
164
165Keys in the JOSE layer use a `struct lws_jwk`, this contains two arrays of
166`struct lws_jwk_elements` sized for the worst case (currently RSA).  One
167array contains the key elements as described for the generic case, and the
168other contains various nonencrypted key metadata taken from JWK JSON.
169
170|metadata index|function|
171|---|---|
172|`JWK_META_KTY`|Key type, eg, "EC"|
173|`JWK_META_KID`|Arbitrary ID string|
174|`JWK_META_USE`|What the public key may be used to validate, "enc" or "sig"|
175|`JWK_META_KEY_OPS`|Which operations the key is authorized for, eg, "encrypt"|
176|`JWK_META_X5C`|Optional X.509 cert version of the key|
177|`JWK_META_ALG`|Optional overall crypto algorithm the key is intended for use with|
178
179`lws_jwk_destroy()` should be called when the jwk is going out of scope... this
180takes care to zero down any key element data in the jwk.
181
182