From bb7be628a008fafe9d36dd330cb6f4d5e34b892e Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Mon, 31 Jan 2022 16:06:12 +0530 Subject: [PATCH] Digital Signature (ds):) Update the documentation for esp_ds_sign and esp_ds_start_sign with additional information. ii) Updated the DS docs for signature calculation. Closes https://github.com/espressif/esp-idf/issues/8242 --- .../esp_hw_support/include/soc/esp32c3/esp_ds.h | 14 ++++++++++++-- .../esp_hw_support/include/soc/esp32h2/esp_ds.h | 15 +++++++++++++-- .../esp_hw_support/include/soc/esp32s2/esp_ds.h | 16 ++++++++++++++-- .../esp_hw_support/include/soc/esp32s3/esp_ds.h | 16 ++++++++++++++-- docs/en/api-reference/peripherals/ds.rst | 4 +++- 5 files changed, 56 insertions(+), 9 deletions(-) diff --git a/components/esp_hw_support/include/soc/esp32c3/esp_ds.h b/components/esp_hw_support/include/soc/esp32c3/esp_ds.h index 9d59aa71c6..3f5aaf6f0b 100644 --- a/components/esp_hw_support/include/soc/esp32c3/esp_ds.h +++ b/components/esp_hw_support/include/soc/esp32c3/esp_ds.h @@ -101,6 +101,11 @@ typedef struct { /** * @brief Sign the message with a hardware key from specific key slot. + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. * * This function is a wrapper around \c esp_ds_finish_sign() and \c esp_ds_start_sign(), so do not use them * in parallel. @@ -108,7 +113,7 @@ typedef struct { * * @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data @@ -134,11 +139,16 @@ esp_err_t esp_ds_sign(const void *message, * * This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing * process. + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. * * @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call * \c esp_ds_finish_sign() in a timely manner. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data diff --git a/components/esp_hw_support/include/soc/esp32h2/esp_ds.h b/components/esp_hw_support/include/soc/esp32h2/esp_ds.h index 6bad707558..bf5a818027 100644 --- a/components/esp_hw_support/include/soc/esp32h2/esp_ds.h +++ b/components/esp_hw_support/include/soc/esp32h2/esp_ds.h @@ -101,6 +101,11 @@ typedef struct { /** * @brief Sign the message with a hardware key from specific key slot. + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. * * This function is a wrapper around \c esp_ds_finish_sign() and \c esp_ds_start_sign(), so do not use them * in parallel. @@ -108,7 +113,7 @@ typedef struct { * * @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data @@ -135,10 +140,16 @@ esp_err_t esp_ds_sign(const void *message, * This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing * process. * + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. + * * @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call * \c esp_ds_finish_sign() in a timely manner. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data diff --git a/components/esp_hw_support/include/soc/esp32s2/esp_ds.h b/components/esp_hw_support/include/soc/esp32s2/esp_ds.h index 2ef0bd00fb..67a4a2f6ca 100644 --- a/components/esp_hw_support/include/soc/esp32s2/esp_ds.h +++ b/components/esp_hw_support/include/soc/esp32s2/esp_ds.h @@ -92,9 +92,15 @@ typedef struct { * in parallel. * It blocks until the signing is finished and then returns the signature. * + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. + * * @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data @@ -121,10 +127,16 @@ esp_err_t esp_ds_sign(const void *message, * This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing * process. * + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. + * * @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call * \c esp_ds_finish_sign() in a timely manner. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data diff --git a/components/esp_hw_support/include/soc/esp32s3/esp_ds.h b/components/esp_hw_support/include/soc/esp32s3/esp_ds.h index 46a1d22a54..5f4d982111 100644 --- a/components/esp_hw_support/include/soc/esp32s3/esp_ds.h +++ b/components/esp_hw_support/include/soc/esp32s3/esp_ds.h @@ -94,9 +94,15 @@ typedef struct { * in parallel. * It blocks until the signing is finished and then returns the signature. * + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. + * * @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data @@ -123,10 +129,16 @@ esp_err_t esp_ds_sign(const void *message, * This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing * process. * + * The function calculates a plain RSA signature with help of the DS peripheral. + * The RSA encryption operation is as follows: + * Z = XY mod M where, + * Z is the signature, X is the input message, + * Y and M are the RSA private key parameters. + * * @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call * \c esp_ds_finish_sign() in a timely manner. * - * @param message the message to be signed; its length is determined by data->rsa_length + * @param message the message to be signed; its length should be (data->rsa_length +1 )*4 bytes * @param data the encrypted signing key data (AES encrypted RSA key + IV) * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the * signing key data diff --git a/docs/en/api-reference/peripherals/ds.rst b/docs/en/api-reference/peripherals/ds.rst index 0e1b506ba8..78308185e1 100644 --- a/docs/en/api-reference/peripherals/ds.rst +++ b/docs/en/api-reference/peripherals/ds.rst @@ -43,6 +43,8 @@ The first one is :cpp:func:`esp_ds_sign` and simply blocks until the calculation If software needs to do something else during the calculation, :cpp:func:`esp_ds_start_sign` can be called, followed by periodic calls to :cpp:func:`esp_ds_is_busy` to check when the calculation has finished. Once the calculation has finished, :cpp:func:`esp_ds_finish_sign` can be called to get the resulting signature. +The APIs :cpp:func:`esp_ds_sign` and :cpp:func:`esp_ds_start_sign` calculate a plain RSA signature with help of the DS peripheral. This signature needs to be converted to appropriate format for further use. For example, MbedTLS SSL stack supports PKCS#1 format. The API :cpp:func:`esp_ds_rsa_sign` can be used to obtain the signature directly in the PKCS#1 v1.5 format. It internally uses :cpp:func:`esp_ds_start_sign` and converts the signature into PKCS#1 v1.5 format. + .. note:: Note that this is only the basic DS building block, the message length is fixed. To create signatures of arbitrary messages, the input is normally a hash of the actual message, padded up to the required length. @@ -67,7 +69,7 @@ More details about the `configure_ds.py` script can be found at :example_file:`m The encrypted private key parameters obtained after the DS peripheral configuration are then to be kept in flash. Furthermore, they are to be passed to the DS peripheral which makes use of those parameters for the Digital Signature operation. :doc:`Non Volatile Storage<../storage/nvs_flash>` can be used to store the encrypted private key parameters in flash. The script :example_file:`configure_ds.py` creates an NVS partition for the encrypted private key parameters. Then the script flashes this partition onto the {IDF_TARGET_NAME}. -The application then needs to read the DS data from NVS, which can be done with the function `esp_read_ds_data_from_nvs` in file :example_file:`ssl_mutual_auth/main/app_main.c ` +The application then needs to read the DS data from NVS, which can be done with the function ``esp_read_ds_data_from_nvs()`` in file :example_file:`ssl_ds/main/app_main.c ` The process of initializing the DS peripheral and then performing the Digital Signature operation is done internally with help of `ESP-TLS`. Please refer to `Digital Signature with ESP-TLS` in :doc:`ESP-TLS <../protocols/esp_tls>` for more details. As mentioned in the `ESP-TLS` documentation, the application only needs to provide the encrypted private key parameters to the esp_tls context (as `ds_data`), which internally performs