oaep.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <debug.h>
  32. #include <malloc.h>
  33. #include <string.h>
  34. #include <platform/oaep.h>
  35. #include <platform/rnd.h>
  36. #include <platform/sha256_export.h>
  37. #include <platform/rsa2048_export.h>
  38. #include <pal_typedefs.h>
  39. /* assume hash: sha256, rsa: rsa2048 */
  40. #define MGF1_COUNTER_SZ (4)
  41. #define SEED_SZ (SHA256_HASH_SZ)
  42. #define DB_SZ (RSA_MODULUS_SZ - 1 - SHA256_HASH_SZ)
  43. /* used OAEP prefix to avoid name collision */
  44. #define OAEP_MIN(a, b) ((a) < (b) ? (a) : (b))
  45. #define ZERO_HASH 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, \
  46. 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, \
  47. 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, \
  48. 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
  49. /* for debug purpose */
  50. static void dump_buf(const uint8_t *buf, uint32_t buf_sz)
  51. {
  52. uint32_t idx = 0;
  53. if (buf_sz < 4)
  54. return;
  55. for (idx = 0; idx <= buf_sz - 4; idx += 4) {
  56. dprintf(CRITICAL, "[0x%x] 0x%x 0x%x 0x%x 0x%x\n", idx,
  57. *(buf + idx),
  58. *(buf + idx + 1),
  59. *(buf + idx + 2),
  60. *(buf + idx + 3));
  61. }
  62. return;
  63. }
  64. static uint32_t i2osp(uint32_t integer,
  65. uint8_t *osp,
  66. uint32_t osp_sz)
  67. {
  68. uint32_t ret = OAEP_OK;
  69. int idx = 0;
  70. memset(osp, 0x0, osp_sz);
  71. if (osp_sz < 1)
  72. return OAEP_I2OSP_FAIL;
  73. idx = osp_sz - 1;
  74. while (integer != 0) {
  75. osp[idx] = integer % 0x100;
  76. integer /= 0x100;
  77. idx--;
  78. if (idx < 0) {
  79. ret = OAEP_I2OSP_FAIL;
  80. break;
  81. }
  82. }
  83. return ret;
  84. }
  85. static uint32_t mgf1(uint8_t *seed,
  86. uint32_t seed_sz,
  87. uint8_t *mask,
  88. uint32_t mask_sz)
  89. {
  90. uint32_t ret = OAEP_OK;
  91. uint32_t counter = 0;
  92. uint32_t num_round = 0;
  93. uint8_t *input = NULL;
  94. uint32_t input_sz = 0;
  95. uint8_t hash[SHA256_HASH_SZ] = {0};
  96. if (NULL == seed)
  97. return OAEP_MGF1_INVALID_SEED_BUF;
  98. if (0 == seed_sz)
  99. return OAEP_MGF1_INVALID_SEED_BUF_SZ;
  100. if (NULL == mask)
  101. return OAEP_MGF1_INVALID_MASK_BUF;
  102. if (0 == mask_sz)
  103. return OAEP_MGF1_INVALID_MASK_BUF_SZ;
  104. input_sz = seed_sz + MGF1_COUNTER_SZ;
  105. input = (uint8_t *)malloc(input_sz);
  106. if (NULL == input) {
  107. ret = OAEP_MGF1_MALLOC_FAIL;
  108. return ret;
  109. }
  110. memcpy(input, seed, seed_sz * sizeof(char));
  111. num_round = (mask_sz + SHA256_HASH_SZ - 1) / SHA256_HASH_SZ;
  112. for (counter = 0; counter < num_round; counter++) {
  113. int hash_ret = 0;
  114. ret = i2osp(counter, input + seed_sz, MGF1_COUNTER_SZ);
  115. if (ret)
  116. goto end;
  117. hash_ret = sha256(input, input_sz, hash);
  118. if (hash_ret) {
  119. ret = OAEP_MGF1_HASH_FAIL;
  120. goto end;
  121. }
  122. memcpy(mask + counter * SHA256_HASH_SZ,
  123. hash,
  124. OAEP_MIN(mask_sz - counter * SHA256_HASH_SZ, SHA256_HASH_SZ));
  125. }
  126. end:
  127. if (NULL != input)
  128. free(input);
  129. return ret;
  130. }
  131. uint32_t oaep_encode(uint8_t *msg,
  132. uint32_t msg_sz,
  133. uint8_t *encoded_msg,
  134. uint32_t encoded_msg_sz)
  135. {
  136. uint32_t ret = OAEP_OK;
  137. const char zero_hash[SEED_SZ] = {ZERO_HASH};
  138. uint8_t *const masked_seed = encoded_msg + 1;
  139. uint8_t *const masked_db = encoded_msg + 1 + SEED_SZ;
  140. /* temp data */
  141. uint8_t seed_mask[SEED_SZ] = {0};
  142. uint8_t db_mask[DB_SZ] = {0};
  143. uint32_t idx = 0;
  144. if (NULL == msg) {
  145. ret = OAEP_INVALID_MSG_BUF;
  146. goto end;
  147. }
  148. if (0 == msg_sz) {
  149. ret = OAEP_INVALID_MSG_BUF_SZ;
  150. goto end;
  151. }
  152. if (NULL == encoded_msg) {
  153. ret = OAEP_INVALID_EMSG_BUF;
  154. goto end;
  155. }
  156. if (0 == encoded_msg_sz) {
  157. ret = OAEP_INVALID_EMSG_BUF_SZ;
  158. goto end;
  159. }
  160. if (RSA_MODULUS_SZ != encoded_msg_sz) {
  161. ret = OAEP_INVALID_EMSG_BUF_SZ;
  162. goto end;
  163. }
  164. if (msg_sz > DB_SZ - SEED_SZ - 1) {
  165. ret = OAEP_MSG_TOO_LONG;
  166. goto end;
  167. }
  168. memset(encoded_msg, 0x0, encoded_msg_sz);
  169. /* get seed from random number generator */
  170. if ((SEED_SZ % sizeof(uint32_t)) != 0) {
  171. ret = OAEP_INVALID_SEED_SZ;
  172. goto end;
  173. }
  174. for (idx = 0; idx < SEED_SZ; idx += 4) {
  175. uint32_t rnd_val = 0;
  176. ret = get_rnd(&rnd_val);
  177. if (ret)
  178. goto end;
  179. memcpy(masked_seed + idx, &rnd_val, sizeof(uint32_t));
  180. }
  181. /* store db in masked_db, mask not applied yet */
  182. memcpy(masked_db, zero_hash, SHA256_HASH_SZ);
  183. masked_db[DB_SZ - msg_sz - 1] = 0x1;
  184. memcpy(masked_db + DB_SZ - msg_sz, msg, msg_sz);
  185. /* create db_mask */
  186. ret = mgf1(masked_seed, SEED_SZ, db_mask, DB_SZ);
  187. if (ret)
  188. goto end;
  189. /* apply db_mask to create masked_db */
  190. for (idx = 0; idx < DB_SZ; idx++)
  191. masked_db[idx] ^= db_mask[idx];
  192. /* create seed_mask */
  193. ret = mgf1(masked_db, DB_SZ, seed_mask, SEED_SZ);
  194. if (ret)
  195. goto end;
  196. /* apply seed_mask to create masked_seed */
  197. for (idx = 0; idx < SEED_SZ; idx++)
  198. masked_seed[idx] ^= seed_mask[idx];
  199. end:
  200. if (ret)
  201. dprintf(CRITICAL, "[oaep] encode fail (0x%x)\n", ret);
  202. return ret;
  203. }
  204. uint32_t oaep_decode(uint8_t *encoded_msg,
  205. uint32_t encoded_msg_sz,
  206. uint8_t *msg,
  207. uint32_t *msg_sz)
  208. {
  209. uint32_t ret = OAEP_OK;
  210. const uint8_t zero_hash[SEED_SZ] = {ZERO_HASH};
  211. uint8_t *const masked_seed = encoded_msg + 1;
  212. uint8_t *const masked_db = encoded_msg + 1 + SEED_SZ;
  213. /* temp data */
  214. uint8_t seed_mask[SEED_SZ] = {0};
  215. uint8_t db_mask[DB_SZ] = {0};
  216. uint32_t idx = 0;
  217. if (NULL == msg) {
  218. ret = OAEP_INVALID_MSG_BUF;
  219. goto end;
  220. }
  221. if (NULL == msg_sz) {
  222. ret = OAEP_INVALID_MSG_BUF_SZ;
  223. goto end;
  224. }
  225. if (0 == *msg_sz) {
  226. ret = OAEP_INVALID_MSG_BUF_SZ;
  227. goto end;
  228. }
  229. if (NULL == encoded_msg) {
  230. ret = OAEP_INVALID_EMSG_BUF;
  231. goto end;
  232. }
  233. if (0 == encoded_msg_sz) {
  234. ret = OAEP_INVALID_EMSG_BUF_SZ;
  235. goto end;
  236. }
  237. if (RSA_MODULUS_SZ != encoded_msg_sz) {
  238. ret = OAEP_INVALID_EMSG_BUF_SZ;
  239. goto end;
  240. }
  241. memset(msg, 0x0, *msg_sz);
  242. /* recover seed_mask */
  243. ret = mgf1(masked_db, DB_SZ, seed_mask, SEED_SZ);
  244. if (ret)
  245. goto end;
  246. /* recover seed */
  247. /* after this step, data in masked_seed is actually seed */
  248. for (idx = 0; idx < SEED_SZ; idx++)
  249. masked_seed[idx] ^= seed_mask[idx];
  250. /* recover db_mask */
  251. ret = mgf1(masked_seed, SEED_SZ, db_mask, DB_SZ);
  252. if (ret)
  253. goto end;
  254. /* recover db */
  255. /* after this step, data in masked_db is actually db */
  256. for (idx = 0; idx < DB_SZ; idx++)
  257. masked_db[idx] ^= db_mask[idx];
  258. /* check against zero hash */
  259. if (0 != memcmp(masked_db, zero_hash, SHA256_HASH_SZ)) {
  260. ret = OAEP_ZERO_HASH_CHK_FAIL;
  261. dprintf(CRITICAL, "[oaep] zero hash compare fail\n");
  262. dprintf(CRITICAL, "[oaep] zero hash:\n");
  263. dump_buf(zero_hash, SHA256_HASH_SZ);
  264. dprintf(CRITICAL, "[oaep] db:\n");
  265. dump_buf(masked_db, DB_SZ);
  266. goto end;
  267. }
  268. for (idx = SHA256_HASH_SZ; idx < DB_SZ; idx++) {
  269. if (masked_db[idx] == 0)
  270. continue;
  271. else if (masked_db[idx] == 1)
  272. break;
  273. else {
  274. ret = OAEP_INVALID_FORMAT;
  275. goto end;
  276. }
  277. }
  278. /* msg starts at idx + 1 */
  279. if (DB_SZ - idx - 1 > *msg_sz) {
  280. ret = OAEP_INVALID_MSG_BUF_SZ;
  281. goto end;
  282. }
  283. *msg_sz = DB_SZ - idx - 1;
  284. memcpy(msg, masked_db + idx + 1, *msg_sz);
  285. end:
  286. if (ret)
  287. dprintf(CRITICAL, "[oaep] decode fail (0x%x)\n", ret);
  288. return ret;
  289. }