pcphmacca.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. * Copyright (C) 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 "owndefs.h"
  32. #include "owncp.h"
  33. #include "pcphmac.h"
  34. #include "pcptool.h"
  35. /*F*
  36. // Name: ippsHMAC_GetSize
  37. //
  38. // Purpose: Returns size of HMAC state (bytes).
  39. //
  40. // Returns: Reason:
  41. // ippStsNullPtrErr pSzie == NULL
  42. // ippStsNoErr no errors
  43. //
  44. // Parameters:
  45. // pSize pointer to the HMAC state size
  46. //
  47. *F*/
  48. IPPFUN(IppStatus, ippsHMAC_GetSize,(int* pSize))
  49. {
  50. /* test size's pointer */
  51. IPP_BAD_PTR1_RET(pSize);
  52. *pSize = sizeof(IppsHMACState);
  53. return ippStsNoErr;
  54. }
  55. /*F*
  56. // Name: ippsHMAC_Init
  57. //
  58. // Purpose: Init HMAC state.
  59. //
  60. // Returns: Reason:
  61. // ippStsNullPtrErr pKey == NULL
  62. // pState == NULL
  63. // ippStsLengthErr keyLen <0
  64. // ippStsNotSupportedModeErr if algID is not match to supported hash alg
  65. // ippStsNoErr no errors
  66. //
  67. // Parameters:
  68. // pKey pointer to the secret key
  69. // keyLen length (bytes) of the secret key
  70. // pState pointer to the HMAC state
  71. // hashAlg hash alg ID
  72. //
  73. *F*/
  74. IPPFUN(IppStatus, ippsHMAC_Init,(const Ipp8u* pKey, int keyLen, IppsHMACState* pCtx, IppHashAlgId hashAlg))
  75. {
  76. //int mbs;
  77. /* get algorithm id */
  78. hashAlg = cpValidHashAlg(hashAlg);
  79. /* test hash alg */
  80. IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr);
  81. //mbs = cpHashMBS(hashAlg);
  82. /* test pState pointer */
  83. IPP_BAD_PTR1_RET(pCtx);
  84. /* test key pointer and key length */
  85. IPP_BAD_PTR1_RET(pKey);
  86. IPP_BADARG_RET(0>keyLen, ippStsLengthErr);
  87. /* set state ID */
  88. HMAC_CTX_ID(pCtx) = idCtxHMAC;
  89. /* init hash context */
  90. ippsHashInit(&HASH_CTX(pCtx), hashAlg);
  91. {
  92. int n;
  93. /* hash specific */
  94. IppsHashState* pHashCtx = &HASH_CTX(pCtx);
  95. int mbs = cpHashMBS(hashAlg);
  96. int hashSize = cpHashSize(hashAlg);
  97. /* copyMask = keyLen>mbs? 0xFF : 0x00 */
  98. int copyMask = (mbs-keyLen) >>(BITSIZE(int)-1);
  99. /* actualKeyLen = keyLen>mbs? hashSize:keyLen */
  100. int actualKeyLen = (hashSize & copyMask) | (keyLen & ~copyMask);
  101. /* compute hash(key, keyLen) just in case */
  102. ippsHashUpdate(pKey, keyLen, pHashCtx);
  103. ippsHashFinal(HASH_BUFF(pHashCtx), pHashCtx);
  104. /* copy either key or hash(key) into ipad- and opad- buffers */
  105. MASKED_COPY_BNU(pCtx->ipadKey, (Ipp8u)copyMask, HASH_BUFF(pHashCtx), pKey, actualKeyLen);
  106. MASKED_COPY_BNU(pCtx->opadKey, (Ipp8u)copyMask, HASH_BUFF(pHashCtx), pKey, actualKeyLen);
  107. /* XOR-ing key */
  108. for(n=0; n<actualKeyLen; n++) {
  109. pCtx->ipadKey[n] ^= (Ipp8u)IPAD;
  110. pCtx->opadKey[n] ^= (Ipp8u)OPAD;
  111. }
  112. for(; n<mbs; n++) {
  113. pCtx->ipadKey[n] = (Ipp8u)IPAD;
  114. pCtx->opadKey[n] = (Ipp8u)OPAD;
  115. }
  116. /* ipad key processing */
  117. ippsHashUpdate(pCtx->ipadKey, mbs, pHashCtx);
  118. return ippStsNoErr;
  119. }
  120. }
  121. /*F*
  122. // Name: ippsHMAC_Update
  123. //
  124. // Purpose: Updates intermadiate MAC based on input stream.
  125. //
  126. // Returns: Reason:
  127. // ippStsNullPtrErr pSrc == NULL
  128. // pState == NULL
  129. // ippStsContextMatchErr pState->idCtx != idCtxHMAC
  130. // ippStsLengthErr len <0
  131. // ippStsNoErr no errors
  132. //
  133. // Parameters:
  134. // pSrc pointer to the input stream
  135. // len input stream length
  136. // pState pointer to the HMAC state
  137. //
  138. *F*/
  139. IPPFUN(IppStatus, ippsHMAC_Update,(const Ipp8u* pSrc, int len, IppsHMACState* pCtx))
  140. {
  141. /* test state pointers */
  142. IPP_BAD_PTR1_RET(pCtx);
  143. /* test state ID */
  144. IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr);
  145. /* test input length */
  146. IPP_BADARG_RET((len<0), ippStsLengthErr);
  147. /* test source pointer */
  148. IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr);
  149. if(len)
  150. return ippsHashUpdate(pSrc, len, &HASH_CTX(pCtx));
  151. else
  152. return ippStsNoErr;
  153. }
  154. /*F*
  155. // Name: ippsHMAC_Final
  156. //
  157. // Purpose: Stop message digesting and return digest.
  158. //
  159. // Returns: Reason:
  160. // ippStsNullPtrErr pMD == NULL
  161. // pState == NULL
  162. // ippStsContextMatchErr pState->idCtx != idCtxHMAC
  163. // ippStsLengthErr sizeof(DigestMD5) < mdLen <1
  164. // ippStsNoErr no errors
  165. //
  166. // Parameters:
  167. // pMD address of the output digest
  168. // pState pointer to the HMAC state
  169. //
  170. *F*/
  171. IPPFUN(IppStatus, ippsHMAC_Final,(Ipp8u* pMD, int mdLen, IppsHMACState* pCtx))
  172. {
  173. /* test state pointer and ID */
  174. IPP_BAD_PTR1_RET(pCtx);
  175. IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr);
  176. /* test MD pointer and length */
  177. IPP_BAD_PTR1_RET(pMD);
  178. IPP_BADARG_RET(mdLen<=0, ippStsLengthErr);
  179. {
  180. /* hash specific */
  181. IppsHashState* pHashCtx = &HASH_CTX(pCtx);
  182. int mbs = cpHashMBS(HASH_ALG_ID(pHashCtx));
  183. int hashSize = cpHashSize(HASH_ALG_ID(pHashCtx));
  184. if(mdLen>hashSize)
  185. IPP_ERROR_RET(ippStsLengthErr);
  186. /*
  187. // finalize hmac
  188. */
  189. {
  190. /* finalize 1-st step */
  191. Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/8];
  192. IppStatus sts = ippsHashFinal(md, pHashCtx);
  193. if(ippStsNoErr==sts) {
  194. /* perform outer hash */
  195. ippsHashUpdate(pCtx->opadKey, mbs, pHashCtx);
  196. ippsHashUpdate(md, hashSize, pHashCtx);
  197. /* complete HMAC */
  198. ippsHashFinal(md, pHashCtx);
  199. CopyBlock(md, pMD, IPP_MIN(hashSize, mdLen));
  200. /* ready to the next HMAC computation */
  201. ippsHashUpdate(pCtx->ipadKey, mbs, pHashCtx);
  202. }
  203. return sts;
  204. }
  205. }
  206. }
  207. /*F*
  208. // Name: ippsHMAC_GetTag
  209. //
  210. // Purpose: Compute digest with further digesting ability.
  211. //
  212. // Returns: Reason:
  213. // ippStsNullPtrErr pMD == NULL
  214. // pState == NULL
  215. // ippStsContextMatchErr pState->idCtx != idCtxHMAC
  216. // ippStsLengthErr size_of_digest < mdLen <1
  217. // ippStsNoErr no errors
  218. //
  219. // Parameters:
  220. // pMD address of the output digest
  221. // mdLen length of the digest
  222. // pState pointer to the HMAC state
  223. //
  224. *F*/
  225. IPPFUN(IppStatus, ippsHMAC_GetTag,(Ipp8u* pMD, int mdLen, const IppsHMACState* pCtx))
  226. {
  227. /* test state pointer and ID */
  228. IPP_BAD_PTR1_RET(pCtx);
  229. IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr);
  230. /* test MD pointer */
  231. IPP_BAD_PTR1_RET(pMD);
  232. {
  233. IppsHMACState tmpCtx;
  234. CopyBlock(pCtx, &tmpCtx, sizeof(IppsHMACState));
  235. return ippsHMAC_Final(pMD, mdLen, &tmpCtx);
  236. }
  237. }
  238. /*F*
  239. // Name: ippsHMAC_Message
  240. //
  241. // Purpose: MAC of the whole message.
  242. //
  243. // Returns: Reason:
  244. // ippStsNullPtrErr pMsg == NULL
  245. // pKey == NULL
  246. // pMD == NULL
  247. // ippStsLengthErr msgLen <0
  248. // keyLen <0
  249. // size_of_digest < mdLen <1
  250. // ippStsNotSupportedModeErr if algID is not match to supported hash alg
  251. // ippStsNoErr no errors
  252. //
  253. // Parameters:
  254. // pMsg pointer to the input message
  255. // msgLen input message length
  256. // pKey pointer to the secret key
  257. // keyLen secret key length
  258. // pMD pointer to message digest
  259. // mdLen MD length
  260. // hashAlg hash alg ID
  261. //
  262. *F*/
  263. IPPFUN(IppStatus, ippsHMAC_Message,(const Ipp8u* pMsg, int msgLen,
  264. const Ipp8u* pKey, int keyLen,
  265. Ipp8u* pMD, int mdLen,
  266. IppHashAlgId hashAlg))
  267. {
  268. /* get algorithm id */
  269. hashAlg = cpValidHashAlg(hashAlg);
  270. /* test hash alg */
  271. IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr);
  272. /* test secret key pointer and length */
  273. IPP_BAD_PTR1_RET(pKey);
  274. IPP_BADARG_RET((keyLen<0), ippStsLengthErr);
  275. /* test input message pointer and length */
  276. IPP_BADARG_RET((msgLen<0), ippStsLengthErr);
  277. IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr);
  278. /* test MD pointer and length */
  279. IPP_BAD_PTR1_RET(pMD);
  280. IPP_BADARG_RET(0>=mdLen || mdLen>cpHashSize(hashAlg), ippStsLengthErr);
  281. {
  282. IppsHMACState ctx;
  283. IppStatus sts = ippsHMAC_Init(pKey, keyLen, &ctx, hashAlg);
  284. if(ippStsNoErr!=sts) goto exit;
  285. sts = ippsHashUpdate(pMsg,msgLen, &HASH_CTX(&ctx));
  286. if(ippStsNoErr!=sts) goto exit;
  287. sts = ippsHMAC_Final(pMD, mdLen, &ctx);
  288. exit:
  289. PurgeBlock(&ctx, sizeof(IppsHMACState));
  290. return sts;
  291. }
  292. }