main.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /**
  2. * Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. /**
  41. * @defgroup nrf_crypto_ecdsa_example
  42. * @{
  43. * @ingroup nrf_crypto_ecdsa
  44. * @brief ECDSA Example Application main file.
  45. *
  46. * This file contains the source code for a sample application that demonstrates using the
  47. * nrf_crypto library to do ECDSA signature generation and verification. Different backends can be
  48. * used by adjusting @ref sdk_config.h accordingly.
  49. *
  50. */
  51. #include <stdbool.h>
  52. #include <stdint.h>
  53. #include <string.h>
  54. #include "sdk_common.h"
  55. #include "nrf_assert.h"
  56. #include "app_error.h"
  57. #include "nrf_log.h"
  58. #include "nrf_log_ctrl.h"
  59. #include "nrf_log_default_backends.h"
  60. #include "nrf_crypto.h"
  61. #include "nrf_crypto_ecc.h"
  62. #include "nrf_crypto_error.h"
  63. #include "nrf_crypto_ecdsa.h"
  64. #include "mem_manager.h"
  65. /** @brief SHA-256 hash digest of the message "Hello bob!
  66. *
  67. * @note If you need to calculate a hash digest from message, please use
  68. * @ref nrf_crypto_hash.
  69. */
  70. static uint8_t m_hash[] =
  71. {
  72. // SHA256("Hello Bob!")
  73. 0x42, 0xba, 0x83, 0x54, 0xdb, 0x26, 0x3a, 0x6a,
  74. 0x5a, 0x9f, 0x74, 0xd6, 0xb7, 0xce, 0xb4, 0xc9,
  75. 0x62, 0xa3, 0xd8, 0xfd, 0x58, 0xa4, 0x19, 0x69,
  76. 0xe5, 0x21, 0xeb, 0x02, 0x22, 0x45, 0x54, 0x15,
  77. };
  78. /** @brief Signature that Alice will generate and Bob will later verify.
  79. */
  80. static nrf_crypto_ecdsa_secp256r1_signature_t m_signature;
  81. /** @brief Size of the signature generated by Alice.
  82. */
  83. static size_t m_signature_size;
  84. //======================================== Print functions ========================================
  85. //
  86. // Utility functions used to print results generated in this examples.
  87. //
  88. static void print_array(uint8_t const * p_string, size_t size)
  89. {
  90. #if NRF_LOG_ENABLED
  91. size_t i;
  92. NRF_LOG_RAW_INFO(" ");
  93. for(i = 0; i < size; i++)
  94. {
  95. NRF_LOG_RAW_INFO("%02x", p_string[i]);
  96. }
  97. #endif // NRF_LOG_ENABLED
  98. }
  99. static void print_hex(char const * p_msg, uint8_t const * p_data, size_t size)
  100. {
  101. NRF_LOG_INFO(p_msg);
  102. print_array(p_data, size);
  103. NRF_LOG_RAW_INFO("\r\n");
  104. }
  105. #define DEMO_ERROR_CHECK(error) \
  106. do \
  107. { \
  108. if (error != NRF_SUCCESS) \
  109. { \
  110. NRF_LOG_ERROR("Error 0x%04X: %s", error, nrf_crypto_error_string_get(error));\
  111. APP_ERROR_CHECK(error); \
  112. } \
  113. } while(0)
  114. //========================================= Alice's site =========================================
  115. //
  116. // This part of an example contains implementation of Alice's site. Alice have predefined private
  117. // key which she needs to keep secret. She uses this private key to sign "Hello Bob!" message.
  118. //
  119. /** @brief Predefined example private key.
  120. *
  121. * This private key contains some dummy data just to show the functionality. Is should never be
  122. * placed in any practical usage. Is is not secure, because it is filled with ones (in HEX).
  123. */
  124. static const uint8_t m_alice_raw_private_key[] =
  125. {
  126. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // This is an example. DO NOT USE THIS KEY!
  127. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // This is an example. DO NOT USE THIS KEY!
  128. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // This is an example. DO NOT USE THIS KEY!
  129. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // This is an example. DO NOT USE THIS KEY!
  130. };
  131. /** @brief Alice signs the message.
  132. */
  133. static void alice_sign()
  134. {
  135. static nrf_crypto_ecc_private_key_t alice_private_key;
  136. ret_code_t err_code = NRF_SUCCESS;
  137. NRF_LOG_INFO("Alice's signature generation");
  138. // Alice converts her raw private key to internal representation
  139. err_code = nrf_crypto_ecc_private_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
  140. &alice_private_key,
  141. m_alice_raw_private_key,
  142. sizeof(m_alice_raw_private_key));
  143. DEMO_ERROR_CHECK(err_code);
  144. // Alice generates signature using ECDSA and SHA-256
  145. m_signature_size = sizeof(m_signature);
  146. err_code = nrf_crypto_ecdsa_sign(NULL,
  147. &alice_private_key,
  148. m_hash,
  149. sizeof(m_hash),
  150. m_signature,
  151. &m_signature_size);
  152. DEMO_ERROR_CHECK(err_code);
  153. // Alice can now send the message and its signature to Bob
  154. print_hex("Alice's message hash: ", m_hash, sizeof(m_hash));
  155. print_hex("Alice's signature: ", m_signature, m_signature_size);
  156. // Key deallocation
  157. err_code = nrf_crypto_ecc_private_key_free(&alice_private_key);
  158. DEMO_ERROR_CHECK(err_code);
  159. }
  160. //========================================== Bob's site ==========================================
  161. //
  162. // This part of the example contains implementation of Bobs's site. Bob has a public generated from
  163. // Alice's private key. The public key is not secret and it could have been shared beforehand, by a
  164. // key-exchange scheme, or by using another authenticated message exchange.
  165. //
  166. // He will use the public key it to verify authenticity of the message, i.e. check if the
  167. // message is actually from Alice.
  168. //
  169. /** @brief Predefined example public key that is associated with example private key
  170. * @ref m_alice_raw_private_key.
  171. */
  172. static const uint8_t m_alice_raw_public_key[] =
  173. {
  174. 0x02, 0x17, 0xE6, 0x17, 0xF0, 0xB6, 0x44, 0x39,
  175. 0x28, 0x27, 0x8F, 0x96, 0x99, 0x9E, 0x69, 0xA2,
  176. 0x3A, 0x4F, 0x2C, 0x15, 0x2B, 0xDF, 0x6D, 0x6C,
  177. 0xDF, 0x66, 0xE5, 0xB8, 0x02, 0x82, 0xD4, 0xED,
  178. 0x19, 0x4A, 0x7D, 0xEB, 0xCB, 0x97, 0x71, 0x2D,
  179. 0x2D, 0xDA, 0x3C, 0xA8, 0x5A, 0xA8, 0x76, 0x5A,
  180. 0x56, 0xF4, 0x5F, 0xC7, 0x58, 0x59, 0x96, 0x52,
  181. 0xF2, 0x89, 0x7C, 0x65, 0x30, 0x6E, 0x57, 0x94,
  182. };
  183. /** @brief Bob verifies the signature.
  184. */
  185. void bob_verify()
  186. {
  187. static nrf_crypto_ecc_public_key_t alice_public_key;
  188. ret_code_t err_code = NRF_SUCCESS;
  189. NRF_LOG_INFO("Bob's message verification");
  190. // Bob converts Alice's raw public key to internal representation
  191. err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
  192. &alice_public_key,
  193. m_alice_raw_public_key,
  194. sizeof(m_alice_raw_public_key));
  195. DEMO_ERROR_CHECK(err_code);
  196. // Bob verifies the message using ECDSA and SHA-256
  197. err_code = nrf_crypto_ecdsa_verify(NULL,
  198. &alice_public_key,
  199. m_hash,
  200. sizeof(m_hash),
  201. m_signature,
  202. m_signature_size);
  203. if (err_code == NRF_SUCCESS)
  204. {
  205. NRF_LOG_INFO("Signature is valid. Message is authentic.");
  206. }
  207. else if (err_code == NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE)
  208. {
  209. NRF_LOG_WARNING("Signature is invalid. Message is not authentic.");
  210. }
  211. else
  212. {
  213. DEMO_ERROR_CHECK(err_code);
  214. }
  215. // Key deallocation
  216. err_code = nrf_crypto_ecc_public_key_free(&alice_public_key);
  217. DEMO_ERROR_CHECK(err_code);
  218. }
  219. //========================================= Example entry =========================================
  220. //
  221. /** @brief Function for initializing the nrf log module.
  222. */
  223. static void log_init(void)
  224. {
  225. ret_code_t err_code = NRF_LOG_INIT(NULL);
  226. APP_ERROR_CHECK(err_code);
  227. NRF_LOG_DEFAULT_BACKENDS_INIT();
  228. }
  229. /** @brief Function for application main entry.
  230. */
  231. int main(void)
  232. {
  233. ret_code_t err_code = NRF_SUCCESS;
  234. log_init();
  235. NRF_LOG_INFO("ECDSA example started.\r\n");
  236. err_code = nrf_mem_init();
  237. DEMO_ERROR_CHECK(err_code);
  238. err_code = nrf_crypto_init();
  239. DEMO_ERROR_CHECK(err_code);
  240. alice_sign(); // Alice signs the message
  241. bob_verify(); // Bob verifies the signature
  242. NRF_LOG_INFO("ECDSA example executed successfully.");
  243. for (;;)
  244. {
  245. }
  246. }
  247. /** @}
  248. */