bchlib_cache.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /****************************************************************************
  2. * drivers/bch/bchlib_cache.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <sys/types.h>
  25. #include <stdbool.h>
  26. #include <errno.h>
  27. #include <assert.h>
  28. #include <debug.h>
  29. #include "bch.h"
  30. #if defined(CONFIG_BCH_ENCRYPTION)
  31. # include <nuttx/crypto/crypto.h>
  32. #endif
  33. /****************************************************************************
  34. * Private Functions
  35. ****************************************************************************/
  36. /****************************************************************************
  37. * Name: bch_xor
  38. ****************************************************************************/
  39. #if defined(CONFIG_BCH_ENCRYPTION)
  40. static void bch_xor(uint32_t *R, uint32_t *A, uint32_t *B)
  41. {
  42. R[0] = A[0] ^ B[0];
  43. R[1] = A[1] ^ B[1];
  44. R[2] = A[2] ^ B[2];
  45. R[3] = A[3] ^ B[3];
  46. }
  47. #endif
  48. /****************************************************************************
  49. * Name: bch_cypher
  50. ****************************************************************************/
  51. #if defined(CONFIG_BCH_ENCRYPTION)
  52. static int bch_cypher(FAR struct bchlib_s *bch, int encrypt)
  53. {
  54. int blocks = bch->sectsize / 16;
  55. FAR uint32_t *buffer = (FAR uint32_t *)bch->buffer;
  56. int i;
  57. for (i = 0; i < blocks; i++, buffer += 16 / sizeof(uint32_t) )
  58. {
  59. uint32_t T[4];
  60. uint32_t X[4] =
  61. {
  62. bch->sector, 0, 0, i
  63. };
  64. aes_cypher(X, X, 16, NULL, bch->key, CONFIG_BCH_ENCRYPTION_KEY_SIZE,
  65. AES_MODE_ECB, CYPHER_ENCRYPT);
  66. /* Xor-Encrypt-Xor */
  67. bch_xor(T, X, buffer);
  68. aes_cypher(T, T, 16, NULL, bch->key, CONFIG_BCH_ENCRYPTION_KEY_SIZE,
  69. AES_MODE_ECB, encrypt);
  70. bch_xor(buffer, X, T);
  71. }
  72. return OK;
  73. }
  74. #endif
  75. /****************************************************************************
  76. * Public Functions
  77. ****************************************************************************/
  78. /****************************************************************************
  79. * Name: bchlib_flushsector
  80. *
  81. * Description:
  82. * Flush the current contents of the sector buffer (if dirty)
  83. *
  84. * Assumptions:
  85. * Caller must assume mutual exclusion
  86. *
  87. ****************************************************************************/
  88. int bchlib_flushsector(FAR struct bchlib_s *bch)
  89. {
  90. FAR struct inode *inode;
  91. ssize_t ret = OK;
  92. /* Check if the sector has been modified and is out of synch with the
  93. * media.
  94. */
  95. if (bch->dirty)
  96. {
  97. inode = bch->inode;
  98. #if defined(CONFIG_BCH_ENCRYPTION)
  99. /* Encrypt data as necessary */
  100. bch_cypher(bch, CYPHER_ENCRYPT);
  101. #endif
  102. /* Write the sector to the media */
  103. ret = inode->u.i_bops->write(inode, bch->buffer, bch->sector, 1);
  104. if (ret < 0)
  105. {
  106. ferr("Write failed: %zd\n", ret);
  107. return (int)ret;
  108. }
  109. #if defined(CONFIG_BCH_ENCRYPTION)
  110. /* Computation overhead to save memory for extra sector buffer
  111. * TODO: Add configuration switch for extra sector buffer
  112. */
  113. bch_cypher(bch, CYPHER_DECRYPT);
  114. #endif
  115. /* The sector is now in sync with the media */
  116. bch->dirty = false;
  117. }
  118. return (int)ret;
  119. }
  120. /****************************************************************************
  121. * Name: bchlib_readsector
  122. *
  123. * Description:
  124. * Flush the current contents of the sector buffer (if dirty)
  125. *
  126. * Assumptions:
  127. * Caller must assume mutual exclusion
  128. *
  129. ****************************************************************************/
  130. int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector)
  131. {
  132. FAR struct inode *inode;
  133. ssize_t ret = OK;
  134. if (bch->sector != sector)
  135. {
  136. inode = bch->inode;
  137. ret = bchlib_flushsector(bch);
  138. if (ret < 0)
  139. {
  140. ferr("Flush failed: %zd\n", ret);
  141. return (int)ret;
  142. }
  143. bch->sector = (size_t)-1;
  144. ret = inode->u.i_bops->read(inode, bch->buffer, sector, 1);
  145. if (ret < 0)
  146. {
  147. ferr("Read failed: %zd\n", ret);
  148. return (int)ret;
  149. }
  150. bch->sector = sector;
  151. #if defined(CONFIG_BCH_ENCRYPTION)
  152. bch_cypher(bch, CYPHER_DECRYPT);
  153. #endif
  154. }
  155. return (int)ret;
  156. }