Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 64 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,64 @@
# s2n

s2n is an implementation of the TLS/SSL protocols. It is designed for servers, and supports SSLv3 (disabled by default), TLS1.0, TLS1.1 and TLS1.2. s2n is released and licensed under the Apache License 2.0.

s2n features include:

* **Systematic C safety**<br/>
s2n is written in C, but makes light use of standard C library functions and wraps all buffer handling and serialization in boundary-enforcing checks.
* **Erase on read**<br/> s2n’s copies of decrypted data buffers are erased as they are read by the application.
* **No locking overhead**<br/> There are no mutexes or locks in s2n.
* **Small code base**<br/> Ignoring tests, blank lines and comments, s2n is about 3,000 lines of code.
* **Minimalist feature adoption**<br/> s2n targets servers and aims to satisfy the common use cases, while avoiding little used features. Additionally; features with a history of triggering protocol-level vulnerabilities are not implemented. For example there is no support for session renegotiation or DTLS, and SSLv3 is disabled by default.
* **Table based state-machines**<br/> s2n uses simple tables to drive the TLS/SSL state machines, making it difficult for invalid out-of-order states to arise.
* **Built-in memory protection**<br/> On Linux; data buffers may not be swapped to disk or appear in core dumps.

s2n handles the protocol validation, state machine and buffer handling, while
encryption and decryption are handled by passing simple and opaque data “blobs”
to cryptographic libraries for processing.

At present s2n uses OpenSSL’s libcrypto for the underlying cryptographic operations.
Cryptographic routines have been written in a modular way so that it is also
possible to use BoringSSL, LibreSSL or other cryptographic libraries for these
operations.

s2n has support for the AES128-GCM, AES256-CBC, AES128-CBC, 3DES-CBC and RC4
ciphers, and the RSA and DHE-RSA (a form of perfect forward secrecy) key
exchange algorithms. For more detail about s2n, see the [API Reference](https://github.com/awslabs/s2n/blob/master/docs/USAGE-GUIDE.md),
[Example server](https://github.com/awslabs/s2n/tree/master/bin), and [Backlog](https://github.com/awslabs/s2n/issues).

## Security and vulnerability notifications
If you discover a security vulnerability or issue in s2n we ask that you notify
AWS Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/).
<img src="docs/images/s2n_logo_github.png" alt="s2n">

s2n is a C99 implementation of the TLS/SSL protocols that is designed to be simple, small, fast, and with security as a priority. It is released and licensed under the Apache Software License 2.0.

## Using s2n

The s2n I/O APIs are designed to be intuitive to developers familiar with the widely-used POSIX I/O APIs, and s2n supports blocking, non-blocking and full-duplex I/O. Additionally there are no locks or mutexes within s2n.

For details on building the s2n library and how to use s2n in an application you are developing, see the [API Reference](https://github.com/awslabs/s2n/blob/master/docs/USAGE-GUIDE.md).

## s2n features

s2n implements SSLv3, TLS1.0, TLS1.1 and TLS1.2. For encryption, s2n suppports 128-bit and 256-bit AES, in the CBC and GCM modes, 3DES and RC4. For forward secrecy, s2n supports both DHE and ECDHE. s2n also supports the Server Name Indicator (SNI), Application-Layer Protocol Negotiation (ALPN) and the Online Certificate Status Protocol (OCSP) TLS extensions. SSLv3, RC4 and DHE are each disabled by default for security reasons.

As it can be difficult to keep track of which encryption algorithms and protocols are best to use, s2n features a simple API to use the latest "default" set of preferences. If you prefer to remain on a specific version for backwards compatibility, that is also supported.

/* Use the latest s2n "default" set of ciphersuite and protocol preferences */
s2n_config_set_cipher_preferences(config, "default");

/* Use a specific set of preferences, update when you're ready */
s2n_config_set_cipher_preferences(config, "20150306")

## s2n security mechanisms

Internally s2n takes a systematic approach to data protection and includes several mechanisms designed to improve safety.

##### Small and auditable code base
Ignoring tests, blank lines and comments, s2n is about 6,000 lines of code. s2n's code is also structured and written with a focus on reviewability. All s2n code is subject to code review, and we plan to complete security reviews of s2n on an anual basis.

To date there have been two external code-level reviews of s2n, including one by a commercial security vendor. s2n has also been shared with some trusted members of the broader cryptography, security, and Open Source communities. Any issues discovered are always recorded in the s2n issue tracker.

##### Static analysis, fuzz-testing and penetration testing

In addition to code reviews, s2n is subject to regular static analysis, fuzz-testing and penetration testing. Several penetration tests have occured, including two by commercial vendors.

##### Erase on read
s2n encrypts or erases plaintext data as quickly as possible. For example, decrypted data buffers are erased as they are read by the application.

##### Built-in memory protection
s2n uses operating system features to protect data from being swapped to disk or appearing in core dumps.

##### Minimalist feature adoption
s2n avoids implementing rarely used options and extensions, as well as features with a history of triggering protocol-level vulnerabilities. For example there is no support for session renegotiation or DTLS.

##### Compartmentalized random number generation
The security of TLS and its associated encryption algorithms depends upon secure random number generation. s2n provides every thread with two seperate random number generators. One for "public" randomly generated data which may appear in the clear, and one for "private" data which should remain secret. This approach lessens the risk of potential predictability weaknesses in random number generation algorithms from leaking information across contexts.

##### Modularized encryption
s2n has been structured so that different encryption libraries may be used. Today s2n supports OpenSSL, LibreSSL, BoringSSL and the Apple Common Crypto framework to perform the underlying cryptographic operations.

##### Table based state-machines
s2n uses simple tables to drive the TLS/SSL state machines, making it difficult for invalid out-of-order states to arise.

##### C safety
s2n is written in C, but makes light use of standard C library functions and wraps all memory handling, string handling and serialization in systematic boundary-enforcing checks.

## Security issue notifications
If you discover a potential security issue in s2n we ask that you notify
AWS Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.

If you package or distribute s2n, or use s2n as part of a large multi-user service, you may be elligible for pre-notification of future s2n releases. Please contact [email protected].

## Contributing to s2n
If you are interested in contributing to s2n, please see our [development guide](https://github.com/awslabs/s2n/blob/master/docs/DEVELOPMENT-GUIDE.md).
36 changes: 23 additions & 13 deletions docs/USAGE-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ memory is too low. To check this limit, run:

to raise the limit, consult the documentation for your platform.

## client mode

At this time s2n does not perform certificate validation and client mode is
disabled as a precaution. To enable client mode for testing and development,
set the **S2N_ENABLE_CLIENT_MODE** environment variable.

# s2n API

The API exposed by s2n is the set of functions and declarations that
Expand All @@ -132,7 +138,7 @@ but does accept SSL2.0 hello messages.

## Enums

s2n defines three enum type:
s2n defines three enum types:

typedef enum { S2N_SERVER, S2N_CLIENT } s2n_mode;

Expand All @@ -142,24 +148,28 @@ S2N_SERVER should be used.

typedef enum { S2N_BUILT_IN_BLINDING, S2N_SELF_SERVICE_BLINDING } s2n_blinding;

**s2n_blinding** is used to opt-out of s2n's built-in blinding. By default s2n
will cause a thread to sleep between 1ms and 10 seconds when a tamper evident
record is encountered. S2N_SELF_SERVICE_BLINDING can be used to opt out of this
behaviour. If s2n_recv() returns an error, self-service applications should
call **s2n_connection_get_delay** and pause for the specified number of
microseconds before calling close() or shutdown().
**s2n_blinding** is used to opt-out of s2n's built-in blinding. Blinding is a
mitigation against timing side-channels which in some cases can leak information
about encrypted data. By default s2n will cause a thread to sleep between 1ms and
10 seconds whenever tampering is detected.

Setting the **S2N_SELF_SERVICE_BLINDING** option with **s2n_connection_set_blinding**
turns off this behavior. This is useful for applications that are handling many connections
in a single thread. In that case, if s2n_recv() returns an error, self-service applications
should call **s2n_connection_get_delay** and pause activity on the connection
for the specified number of microseconds before calling close() or shutdown().

typedef enum { S2N_STATUS_REQUEST_NONE, S2N_STATUS_REQUEST_OCSP } s2n_status_request_type;

**s2n_status_request_type** is used to define the type, if any, of certificate
status request an S2N_CLIENT should make during the handshake. The only
supported status request type is OCSP, S2N_STATUS_REQUEST_OCSP.
status request an S2N_CLIENT should make during the handshake. The only
supported status request type is OCSP, **S2N_STATUS_REQUEST_OCSP**.

## Opaque structures

s2n defines two opaque structures that are used for managed objects. These
structures are opaque and can only be safely referenced indirectly through
pointers.
s2n defines two opaque structures that are used for managed objects. Because
these structures are opaque, they can only be safely referenced indirectly through
pointers and their sizes may change with future versions of s2n.

struct s2n_config;
struct s2n_connection;
Expand All @@ -174,7 +184,7 @@ s2n functions that return 'int' return 0 to indicate success and -1 to indicate
failure. s2n functions that return pointer types return NULL in the case of
failure. When an s2n function returns a failure, s2n_errno will be set to a value
corresponding to the error. This error value can be translated into a string
explaining the error by calling s2n_strerror(s2n_errno, "EN");
explaining the error in English by calling s2n_strerror(s2n_errno, "EN");

## Initialization and teardown

Expand Down
Binary file added docs/images/s2n_logo_github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion error/s2n_errno.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ struct s2n_error_translation EN[] = {
{ S2N_ERR_NO_ALERT, "No Alert present" },
{ S2N_ERR_CLIENT_MODE, "operation not allowed in client mode" },
{ S2N_ERR_SERVER_NAME_TOO_LONG, "server name is too long" },
{ S2N_ERR_INSECURE_CLIENT, "client connections not allowed" },
{ S2N_ERR_CLIENT_MODE_DISABLED, "client connections not allowed" },
{ S2N_ERR_HANDSHAKE_STATE, "Invalid handshake state encountered" },
{ S2N_ERR_FALLBACK_DETECTED, "TLS fallback detected" },
{ S2N_ERR_INVALID_CIPHER_PREFERENCES, "Invalid Cipher Preferences version" },
Expand Down
2 changes: 1 addition & 1 deletion error/s2n_errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ typedef enum {
S2N_ERR_NO_ALERT,
S2N_ERR_CLIENT_MODE,
S2N_ERR_SERVER_NAME_TOO_LONG,
S2N_ERR_INSECURE_CLIENT,
S2N_ERR_CLIENT_MODE_DISABLED,
S2N_ERR_HANDSHAKE_STATE,
S2N_ERR_FALLBACK_DETECTED,
S2N_ERR_INVALID_CIPHER_PREFERENCES,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_cipher_suite_match_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ int main(int argc, char **argv)

BEGIN_TEST();

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));

count = 0;
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_client_disabled_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ int main(int argc, char **argv)

EXPECT_NULL(conn = s2n_connection_new(S2N_CLIENT));

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
EXPECT_SUCCESS(s2n_connection_free(conn));

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_client_extensions_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ int main(int argc, char **argv)
{
BEGIN_TEST();

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
EXPECT_SUCCESS(s2n_init());

/* Client doens't use the server name extension. */
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_fragmentation_coalescing_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ int main(int argc, char **argv)

BEGIN_TEST();

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));

/* Create a pipe */
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_handshake_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ int main(int argc, char **argv)

BEGIN_TEST();

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
EXPECT_SUCCESS(s2n_init());

EXPECT_NOT_NULL(server_config = s2n_config_new());
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_malformed_handshake_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ int main(int argc, char **argv)

BEGIN_TEST();

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));

/* Test a good certificate list */
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_self_talk_alpn_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ int main(int argc, char **argv)

BEGIN_TEST();

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));

EXPECT_SUCCESS(s2n_init());
EXPECT_NOT_NULL(config = s2n_config_new());
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_self_talk_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ int main(int argc, char **argv)

BEGIN_TEST();

EXPECT_SUCCESS(setenv("S2N_ENABLE_INSECURE_CLIENT", "1", 0));
EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));

/* Create a pipe */
EXPECT_SUCCESS(s2n_init());
Expand Down
4 changes: 2 additions & 2 deletions tls/s2n_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ struct s2n_connection *s2n_connection_new(s2n_mode mode)
* to use S2N in client mode for testing purposes. An environment
* variable is required to be set for the client mode to work.
*/
if (getenv("S2N_ENABLE_INSECURE_CLIENT") == NULL) {
if (getenv("S2N_ENABLE_CLIENT_MODE") == NULL) {
s2n_free(&blob);
S2N_ERROR_PTR(S2N_ERR_INSECURE_CLIENT);
S2N_ERROR_PTR(S2N_ERR_CLIENT_MODE_DISABLED);
}
}

Expand Down