diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h index 3c5b1336b..da22722b0 100644 --- a/include/mbedtls/aes.h +++ b/include/mbedtls/aes.h @@ -291,6 +291,46 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, unsigned char *output ); #endif /*MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/** + * \brief This function performs an AES-OFB (Output Feedback Mode) encryption + * or decryption operation. + * + * For OFB, you must set up the context with mbedtls_aes_setkey_enc(), + * regardless of whether you are performing an encryption or decryption + * operation. This is because OFB mode uses the same key schedule for + * encryption and decryption. + * + * The OFB operation is identical for encryption or decryption, therefore + * no operation mode needs to be specified. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the + * IV, you must either save it manually or use the cipher + * module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * \param length The length of the input data. + * \param iv_off The offset in IV (updated after use). + * \param iv The initialization vector (updated after use). + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * + * \return \c 0 on success. + */ +int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + #if defined(MBEDTLS_CIPHER_MODE_CTR) /** * \brief This function performs an AES-CTR encryption or decryption diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 9585e6922..1b4bee30d 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -495,6 +495,13 @@ */ #define MBEDTLS_CIPHER_MODE_CBC +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_OFB + /** * \def MBEDTLS_CIPHER_MODE_CFB * diff --git a/library/aes.c b/library/aes.c index da94b1943..529f7f4ec 100644 --- a/library/aes.c +++ b/library/aes.c @@ -1065,7 +1065,36 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, return( 0 ); } -#endif /*MBEDTLS_CIPHER_MODE_CFB */ +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/* + * AES-OFB (Output Feedback Mode) buffer encryption/decryption + */ +int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + size_t n = *iv_off; + + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + *output++ = *input++ ^ iv[n]; + + n = ( n + 1 ) & 0x0F; + } + + *iv_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_OFB */ #if defined(MBEDTLS_CIPHER_MODE_CTR) /* diff --git a/library/version_features.c b/library/version_features.c index a452caf5e..218a8925c 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -246,6 +246,9 @@ static const char *features[] = { #if defined(MBEDTLS_CIPHER_MODE_CBC) "MBEDTLS_CIPHER_MODE_CBC", #endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) + "MBEDTLS_CIPHER_MODE_OFB", +#endif /* MBEDTLS_CIPHER_MODE_OFB */ #if defined(MBEDTLS_CIPHER_MODE_CFB) "MBEDTLS_CIPHER_MODE_CFB", #endif /* MBEDTLS_CIPHER_MODE_CFB */