ecp.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "ecp.h"
  34. #include "sample_libcrypto.h"
  35. #define MAC_KEY_SIZE 16
  36. errno_t memcpy_s(
  37. void *dest,
  38. size_t numberOfElements,
  39. const void *src,
  40. size_t count)
  41. {
  42. if(numberOfElements<count)
  43. return -1;
  44. memcpy(dest, src, count);
  45. return 0;
  46. }
  47. bool verify_cmac128(
  48. sample_ec_key_128bit_t mac_key,
  49. const uint8_t *p_data_buf,
  50. uint32_t buf_size,
  51. const uint8_t *p_mac_buf)
  52. {
  53. uint8_t data_mac[SAMPLE_EC_MAC_SIZE];
  54. sample_status_t sample_ret;
  55. sample_ret = sample_rijndael128_cmac_msg((sample_cmac_128bit_key_t*)mac_key,
  56. p_data_buf,
  57. buf_size,
  58. (sample_cmac_128bit_tag_t *)data_mac);
  59. if(sample_ret != SAMPLE_SUCCESS)
  60. return false;
  61. // In real implementation, should use a time safe version of memcmp here,
  62. // in order to avoid side channel attack.
  63. if(!memcmp(p_mac_buf, data_mac, SAMPLE_EC_MAC_SIZE))
  64. return true;
  65. return false;
  66. }
  67. #define EC_DERIVATION_BUFFER_SIZE(label_length) ((label_length) +4)
  68. const char str_SMK[] = "SMK";
  69. const char str_SK[] = "SK";
  70. const char str_MK[] = "MK";
  71. const char str_VK[] = "VK";
  72. // Derive key from shared key and key id.
  73. // key id should be sample_derive_key_type_t.
  74. bool derive_key(
  75. const sample_ec_dh_shared_t *p_shared_key,
  76. uint8_t key_id,
  77. sample_ec_key_128bit_t* derived_key)
  78. {
  79. sample_status_t sample_ret = SAMPLE_SUCCESS;
  80. uint8_t cmac_key[MAC_KEY_SIZE];
  81. sample_ec_key_128bit_t key_derive_key;
  82. memset(&cmac_key, 0, MAC_KEY_SIZE);
  83. sample_ret = sample_rijndael128_cmac_msg(
  84. (sample_cmac_128bit_key_t *)&cmac_key,
  85. (uint8_t*)p_shared_key,
  86. sizeof(sample_ec_dh_shared_t),
  87. (sample_cmac_128bit_tag_t *)&key_derive_key);
  88. if (sample_ret != SAMPLE_SUCCESS)
  89. {
  90. // memset here can be optimized away by compiler, so please use memset_s on
  91. // windows for production code and similar functions on other OSes.
  92. memset(&key_derive_key, 0, sizeof(key_derive_key));
  93. return false;
  94. }
  95. const char *label = NULL;
  96. uint32_t label_length = 0;
  97. switch (key_id)
  98. {
  99. case SAMPLE_DERIVE_KEY_SMK:
  100. label = str_SMK;
  101. label_length = sizeof(str_SMK) -1;
  102. break;
  103. case SAMPLE_DERIVE_KEY_SK:
  104. label = str_SK;
  105. label_length = sizeof(str_SK) -1;
  106. break;
  107. case SAMPLE_DERIVE_KEY_MK:
  108. label = str_MK;
  109. label_length = sizeof(str_MK) -1;
  110. break;
  111. case SAMPLE_DERIVE_KEY_VK:
  112. label = str_VK;
  113. label_length = sizeof(str_VK) -1;
  114. break;
  115. default:
  116. // memset here can be optimized away by compiler, so please use memset_s on
  117. // windows for production code and similar functions on other OSes.
  118. memset(&key_derive_key, 0, sizeof(key_derive_key));
  119. return false;
  120. break;
  121. }
  122. /* derivation_buffer = counter(0x01) || label || 0x00 || output_key_len(0x0080) */
  123. uint32_t derivation_buffer_length = EC_DERIVATION_BUFFER_SIZE(label_length);
  124. uint8_t *p_derivation_buffer = (uint8_t *)malloc(derivation_buffer_length);
  125. if (p_derivation_buffer == NULL)
  126. {
  127. // memset here can be optimized away by compiler, so please use memset_s on
  128. // windows for production code and similar functions on other OSes.
  129. memset(&key_derive_key, 0, sizeof(key_derive_key));
  130. return false;
  131. }
  132. memset(p_derivation_buffer, 0, derivation_buffer_length);
  133. /*counter = 0x01 */
  134. p_derivation_buffer[0] = 0x01;
  135. /*label*/
  136. memcpy(&p_derivation_buffer[1], label, label_length);
  137. /*output_key_len=0x0080*/
  138. uint16_t *key_len = (uint16_t *)(&(p_derivation_buffer[derivation_buffer_length - 2]));
  139. *key_len = 0x0080;
  140. sample_ret = sample_rijndael128_cmac_msg(
  141. (sample_cmac_128bit_key_t *)&key_derive_key,
  142. p_derivation_buffer,
  143. derivation_buffer_length,
  144. (sample_cmac_128bit_tag_t *)derived_key);
  145. free(p_derivation_buffer);
  146. // memset here can be optimized away by compiler, so please use memset_s on
  147. // windows for production code and similar functions on other OSes.
  148. memset(&key_derive_key, 0, sizeof(key_derive_key));
  149. if (sample_ret != SAMPLE_SUCCESS)
  150. {
  151. return false;
  152. }
  153. return true;
  154. }