1. 程式人生 > >Intel IPP密碼庫 IPPCP 2018 開發筆記與總結(全)

Intel IPP密碼庫 IPPCP 2018 開發筆記與總結(全)

Part I. 開發指南

內容參考官方文件

《Intel® Integrated Performance Primitives Cryptography Developer Guide, Intel Integrated Performance Primitives 2018》

1. Getting Started

路徑說明

  1. 預設的Intel IPP密碼庫安裝路徑<install_dir>為C:/Program files (x86)/IntelSWTools/compilers_and_libraries_2018.x.xxx/<target_os
  2. 預設的Intel IPP密碼庫主檔案目錄<ipp cryptography directory>為<install_dir>/ippcp/.

新增環境變數

  1. 環境變數(執行如下檔案)
    1. <install_dir>\ipp\bin\ippvars.bat
    2. <install_dir>\ippcp\bin\ippcpvars.bat
  2. 手動新增Path
    1. <install_dir>\redist\ ia32_win\ipp
    2. <install_dir>\redist\ intel64_win\ippcp

然後分別執行

  1. <install_dir>\ippcp\tools\ia32\perfsys\ps_ippcp.exe
  2. <install_dir>\ippcp\tools\intel64\perfsys\ps_ippcp.exe

檢測這兩個程式是否能正常執行;正常執行則設定正確。

2. Theory of Operation

預設的介面函式是一個分派介面而已,它會根據CPU型號去分配對於的真正實現的庫。根據CPU型號實現的庫和函式會以該CPU標識為字首。

比如ippsSHA256Update()是一般的介面,內含很多版本。在64-bit 應用的第二代Core處理器會呼叫e9_ippsSHA256Update(),在64-bit 應用的支援SSE4.2的處理器上會呼叫y8_ippsSHA256Update()。

表 CPU型號的字首標識表

3. Linking Your Application

Intel IPP密碼庫支援四種連結方式:單執行緒靜態庫、單執行緒動態庫、多執行緒靜態庫、多執行緒動態庫。

  1. 單執行緒庫已帶,安裝後路徑為

 <ipp cryptography directory>/lib/<arch>

  1. 多執行緒庫需單獨下載,安裝後路徑為

 <ipp cryptography directory>/lib/<arch>/threaded

庫名

單執行緒

多執行緒

靜態庫

ippcpmt.lib

ippcpmt.lib

動態庫

ippcp.lib

ippcp.lib

4. Programming in the VS* IDE

1. VS IDE新增路徑

最好把IPP的相關路徑也新增進去,因為有很多需要IPP。

工具 選項 環境很解決方案 VC目錄,新增對應平臺的include檔案和lib檔案。

  1. include
    1. <install_dir>\ipp\include
    2. <install_dir>\ippcp\include
  2. Lib
    1. <install_dir>\ipp\lib\<arch>_win,<arch> 為ia32或者intel64
    2. <install_dir>\ippcp\lib\<arch>_win,<arch> 為ia32或者intel64
  3. bin(是否需要新增,因為環境變數已經新增)
    1. <install_dir>\redist\<arch>_win\ipp,<arch> 為ia32或intel64
    2. <install_dir>\redist\<arch>_win\ippcp,<arch> 為ia32或intel64

2. 工程新增庫

專案 屬性 配置屬性 連結器 輸入 附加依賴性,新增需要的lib檔案。例如動態連結需要ippcp.lib,靜態連結需要ippcpmt.lib。

附錄A Performance Test Tool

  1. <install_dir>\ippcp\tools\ia32\perfsys\ps_ippcp.exe
  2. <install_dir>\ippcp\tools\intel64\perfsys\ps_ippcp.exe

附錄B Threading and OpenMP

如果應用層已經採用多執行緒來呼叫 IPP 密碼庫,則底層最好使用單執行緒密碼庫。否則,應用層和底層IPP密碼庫都使用多執行緒的話,會出現Nested parallelization,從而導致效率降低。

 

 

Part II. 開發參考手冊

1. Overview

1.1 Function Context Structures

兩種上下文:

  1. Spec為字尾,表示函式操作時不做更改
  2. State為字尾,表示函式操作時要做更改

2. Symmetric Cryptography

2.1加解密步驟

其中<Alg>指具體的密碼演算法,<Mode>指ECB、CBC、OFB、CFB、CTR模式。

執行步驟:

步驟1. 獲取ctx大小:ipps<Alg>GetSize(int* pSize);其中<Alg>指具體的密碼演算法。

步驟2. 記憶體分配:pCtx = malloc(Size),分配Size位元組記憶體給密碼演算法的pCtx;

步驟3. 初始化(金鑰擴充套件):ipps<Alg>Init,需指定金鑰。

步驟4. 加解密:呼叫ipps<Alg>Encrypt<Mode>或者ipps<Alg>Decrypt<Mode>,這裡要設定IV,且IV在執行後會變化。

步驟5. 反初始化(資料清除):呼叫ipps<Alg>Init,但讓key置為NULL。

步驟6. 記憶體釋放:free(pCtx)。

注:

1. 還有個ipps<Alg>SetKey用於重新設定金鑰,功能與ipps<Alg>Init類似;兩者差異未知,猜測可能Init涉及一些別的特殊操作。

2.2 支援的密碼演算法和工作模式

表X 支援的密碼演算法和工作模式

模式演算法

AES

TDES/DES

SM4

ARCFour

ECB

Y

Y

Y

RC4為流密碼

CBC

Y

Y

Y

CFB

Y

Y

Y

OFB

Y

Y

Y

CTR

Y

Y

Y

CCM

Y

X

Y2018版)

GCM

Y

X

X

XTS

Y

X

X

SIV

Y

X

X

補充說明

  1. TDES = DES加密(K1) → DES解密(K2) → DES加密(K1) 。
  2. ARCFour即RC4演算法。
  3. CCM、GCM、SIV為認證加密模式;XTS為磁碟加密模式。

2.3 函式說明

2.3.1 獲取上下文大小GetSize

IppStatus ippsAESGetSize(int* pSize);

IppStatus ippsDESGetSize(int* pSize);

IppStatus ippsSMS4GetSize(int* pSize);

IppStatus ippsARCFourGetSize(int* pSize);

引數說明

  1. pSize:OUT,CTX大小,單位位元組。

2.3.2 初始化和反初始化Init

IppStatus ippsAESInit(const Ipp8u* pKey, int keylen, IppsAESSpec* pCtx, int ctxSize);

IppStatus ippsDESInit(const Ipp8u* pKey, IppsDESSpec* pCtx);

IppStatus ippsSMS4Init(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx, int ctxSize);

IppStatus ippsARCFourInit(const Ipp8u* pKey, int keyLen, IppsARCFourState* pCtx);

引數說明

  1. pKey:IN,金鑰。
  2. keyLen:IN,金鑰位元組長度。
  3. pCtx:OUT,密碼演算法上下文。
  4. ctxSize:IN,CTX大小,單位位元組。

補充說明

  1. SM4的金鑰長度必須是16。RC4金鑰長度為1—256位元組。
  2. 將pKey設定為NULL則執行反初始化。
  3. TDES需要對三個金鑰各執行ippsDESInit以初始化三個IppsDESSpec*。

2.3.3 重置金鑰SetKey

AESSM4有重置金鑰函式

IppStatus ippsAESSetKey(const Ipp8u* pKey, int keylen, IppsAESSpec* pCtx);

IppStatus ippsSMS4SetKey(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx);

引數說明

  1. pKey:IN,金鑰。
  2. keyLen:IN,金鑰位元組長度。
  3. pCtx:OUT,密碼演算法上下文。

補充說明

  1. pCtx必須是已經Init了的才能呼叫此函式。

2.3.4 上下文匯入匯出Pack/Unpack

SM4無上下文匯入匯出。

IppStatus ippsAESPack (const IppsAESSpec* pCtx, Ipp8u* pBuffer, int bufSize);

IppStatus ippsAESUnpack (const Ipp8u* pBuffer, IppsAESSpec* pCtx, int ctxSize);

IppStatus ippsDESPack (const IppsDESSpec* pCtx, Ipp8u* pBuffer);

IppStatus ippsDESUnpack (const Ipp8u* pBuffer, IppsDESSpec* pCtx);

IppStatus ippsARCFourPack (const IppsARCFourState* pCtx, Ipp8u* pBuffer);

IppStatus ippsARCFourUnpack (const Ipp8u* pBuffer, IppsARCFourState* pCtx);

引數說明

A)匯出/Pack

  1. pCtx:IN,上下文。
  2. pBuffer:OUT,匯出緩衝區。
  3. bufSize:IN,有的函式無。

B)匯入/Unpack

  1. pBuffer:IN,匯入緩衝區。
  2. pCtx:OUT,上下文。
  3. ctxSize:IN,上下文。

備註:

  1. 無論緩衝區pBuffer位元組大小還是上下文pCtx位元組大小,都呼叫ipps***GetSize獲得。
  2. SM4無上下文匯入匯出。
  3. AES有bufSize和ctxSize是因為AES的金鑰有三種長度,使得其buf和ctx不定長。

2.3.5 AES加解密

IppStatus ippsAESEncryptECB(       const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsAESSpec* pCtx);

IppStatus ippsAESDecryptECB(        const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx);

IppStatus ippsAESEncryptCBC(       const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC(       const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESEncryptCFB(        const Ipp8u* pSrc, Ipp8u* pDst, int srcLen, int cfbBlkSize, const IppsAESSpec* pCtx, const Ipp8u *pIV);

IppStatus ippsAESDecryptCFB( const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int cfbBlkSize, const IppsAESSpec* pCtx, const Ipp8u*pIV);

IppStatus ippsAESEncryptOFB (      const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsAESSpec* pCtx, Ipp8u* pIV);

IppStatus ippsAESDecryptOFB (       const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsAESSpec* pCtx, Ipp8u* pIV);

IppStatus ippsAESEncryptCTR(       const Ipp8u* pSrc, Ipp8u* pDst, int srcLen,const IppsAESSpec* pCtx, Ipp8u* pCtrValue , int ctrNumBitSize);

IppStatus ippsAESDecryptCTR(       const Ipp8u* pSrc, Ipp8u* pDst, int srcLen,const IppsAESSpec* pCtx, Ipp8u* pCtrValue, int ctrNumBitSize);

以下是在2018版中發現的新增介面,CBCCS模式,2017版無。

IppStatus ippsAESEncryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESEncryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESEncryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

表X 引數列表

AES

pSrc

pDst

srcLen

pCtx

pIV

其它

ECB

Y

Y

Y

Y

CBC

Y

Y

Y

Y

Y

CBC_CS1

Y

Y

Y

Y

Y

CBC_CS2

Y

Y

Y

Y

Y

CBC_CS3

Y

Y

Y

Y

Y

CFB

Y

Y

Y

Y

Y

cfbBlkSize

OFB

Y

Y

Y

Y

Y

ofbBlkSize

CTR

Y

Y

Y

Y

pCtrValue

ctrNumBitSize

引數說明

  1. pSrc:IN,加密時為明文,解密時為密文。
  2. srclen:IN,Src的位元組長度。
  3. pDst:OUT,加密時為密文,解密時為明文。長度等於srclen。
  4. pCtx:IO,密碼演算法上下文。
  5. pIV:IO,初始化向量,長度同分組大小,呼叫後會改變。ECB無。
  6. pCtrValue:IO,CTR的計數器,相當於其它模式的初始化向量。
  7. ctrNumBitSize:IN,計數器中有效的計數位元長度(從右端計)。
  8. cfbBlkSize/ ofbBlkSize:CFB/OFB每拍輸出的金鑰流位元組數,小於分組大小。

備註1CBC_CS採用密文偷取技術,使得資料多次加密時使用不便。因此,建議這種模式下一次性輸入完畢明文/密文。

備註2srcLen長度說明。

表X srcLen說明

AES

srcLen

ECB

16 | srcLen

CBC

16 | srcLen

CFB

cfbBlkSize | srcLen

OFB

ofbBlkSize | srcLen

CTR

任意長度。

但非最後一次呼叫時都要求16 | srcLen

CTRsrcLen長度的進一步說明

若srcLen不是16的整數倍,則生成的多餘的金鑰流會被丟棄。下次再送入資料時,會用新的CTR值加密作為金鑰流。

例如,第1次送入33位元組,第二次再送入31位元組。第一次生成48位元組金鑰流,前33位元組金鑰流用於加密,後15位元組金鑰流丟棄;第二次重新產生32位元組,前31位元組金鑰流用於加密,後1位元組金鑰流丟棄。這樣一來,由於第一次加密時丟棄了15位元組金鑰流,就導致了其加密結果和我們期望的結果不一致。

2.3.6 AES其它模式

AES加密認證涉及CCM、GCM、SIV,詳情參見官方文件。本文件略。

AES磁碟加密涉及XTS模式,詳情參見官方文件。本文件略。

2.3.7 TDES加解密

IppStatus ippsTDESEncryptECB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, IppsCPPadding padding);

IppStatus ippsTDESDecryptECB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, IppsCPPadding padding);

IppStatus ippsTDESEncryptCBC(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESDecryptCBC(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESEncryptCFB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, int cfbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESDecryptCFB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, int cfbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESEncryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, Ipp8u* pIV);

IppStatus ippsTDESDecryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, Ipp8u* pIV);

IppStatus ippsTDESEncryptCTR(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3,Ipp8u *pCtrValue, int ctrNumBitSize);

IppStatus ippsTDESDecryptCTR(const Ipp8u *pSrc, Ipp8u *pDst, int srcLen,const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, Ipp8u *pCtrValue, int ctrNumBitSize);

表X 引數列表

TDES

pSrc

pDst

srcLen

pCtx1-3

pIV

padding

其它

ECB

Y

Y

Y

Y

Y

CBC

Y

Y

Y

Y

Y

Y

CFB

Y

Y

Y

Y

Y

Y

cfbBlkSize

OFB

Y

Y

Y

Y

Y

ofbBlkSize

CTR

Y

Y

Y

Y

pCtrValue

ctrNumBitSize

引數說明

  1. pSrc:IN,加密時為明文,解密時為密文。
  2. srclen:IN,Src的位元組長度。
  3. pDst:OUT,加密時為密文,解密時為明文。長度等於srclen。
  4. pCtx1,pCtx2,pCtx3:IO,密碼演算法上下文,三個金鑰對應三個上下文。
  5. pIV:IO,初始化向量,長度同分組大小,呼叫後會改變。ECB無。
  6. padding:IN,目前好像只支援IppsPaddingNONE(不填充)。具體待查。
  7. pCtrValue:IO,CTR的計數器,相當於其它模式的初始化向量。
  8. ctrNumBitSize:IN,計數器中有效的計數位元長度(從右端計)。
  9. cfbBlkSize/ ofbBlkSize:CFB/OFB每拍輸出的金鑰流位元組數,小於分組大小。

備註:

  1. padding:具體待查。

2.3.8 SM4加解密

IppStatus ippsSMS4EncryptECB(const Ipp8u *pSrc, Ipp8u *pDst, int len, const IppsSMS4Spec* pCtx);

IppStatus ippsSMS4DecryptECB(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx);

IppStatus ippsSMS4EncryptCBC(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx, const Ipp8u* pIV);

IppStatus ippsSMS4DecryptCBC(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx, const Ipp8u* pIV);

IppStatus ippsSMS4EncryptCFB(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, const IppsSMS4Spec* pCtx, const Ipp8u *pIV);

IppStatus ippsSMS4DecryptCFB(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, const IppsSMS4Spec* pCtx, const Ipp8u* pIV);

IppStatus ippsSMS4EncryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, const IppsSMS4Spec* pCtx, Ipp8u* pIV);

IppStatus ippsSMS4DecryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, const IppsSMS4Spec* pCtx, Ipp8u* pIV);

IppStatus ippsSMS4EncryptCTR(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx, Ipp8u* pCtrValue , int ctrNumBitSize);

IppStatus ippsSMS4DecryptCTR(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec * pCtx, Ipp8u* pCtrValue, int ctrNumBitSize);

以下是在2018版中發現的新增介面,CBCCS模式,2017版無。

IppStatus ipps SMS4EncryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4EncryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4EncryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4DecryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4DecryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4DecryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

 

表X 引數列表

SM4

pSrc

pDst

srcLen

pCtx

pIV

其它

ECB

Y

Y

Y

Y

CBC

Y

Y

Y

Y

Y

CBC-CS1

Y

Y

Y

Y

Y

CBC-CS2

Y

Y

Y

Y

Y

CBC-CS3

Y

Y

Y

Y

Y

CFB

Y

Y

Y

Y

Y

cfbBlkSize

OFB

Y

Y

Y

Y

Y

ofbBlkSize

CTR

Y

Y

Y

Y

pCtrValue

ctrNumBitSize

引數說明

  1. pSrc:IN,加密時為明文,解密時為密文。
  2. srclen:IN,Src的位元組長度。
  3. pDst:OUT,加密時為密文,解密時為明文。長度等於srclen。
  4. pCtx:IO,密碼演算法上下文。
  5. pIV:IO,初始化向量,長度同分組大小,呼叫後會改變。ECB無。
  6. pCtrValue:IO,CTR的計數器,相當於其它模式的初始化向量。
  7. ctrNumBitSize:IN,計數器中有效的計數位元長度(從右端計)。
  8. cfbBlkSize/ ofbBlkSize:CFB/OFB每拍輸出的金鑰流位元組數,小於分組大小。

備註1CBC_CS採用密文偷取技術,使得資料多次加密時使用不便。因此,建議這種模式下一次性輸入完畢明文/密文。

備註2srcLen長度說明。

表X srcLen說明

AES

srcLen

ECB

16 | srcLen

CBC

16 | srcLen

CFB

cfbBlkSize | srcLen

OFB

ofbBlkSize | srcLen

CTR

任意長度。

但非最後一次呼叫時都要求16 | srcLen

CTRsrcLen長度的進一步說明

若srcLen不是16的整數倍,則生成的多餘的金鑰流會被丟棄。下次再送入資料時,會用新的CTR值加密作為金鑰流。

例如,第1次送入33位元組,第二次再送入31位元組。第一次生成48位元組金鑰流,前33位元組金鑰流用於加密,後15位元組金鑰流丟棄;第二次重新產生32位元組,前31位元組金鑰流用於加密,後1位元組金鑰流丟棄。這樣一來,由於第一次加密時丟棄了15位元組金鑰流,就導致了其加密結果和我們期望的結果不一致。

2.3.8 SM4-CCM加解認證

在2018版中發現有SM4-CCM,但是SM4執行CCM的可能性較低,所以本部分略。

2.3.9 ARCFour加解密

ARCFour即RC4流密碼。本部分略。

2.4 示例程式碼

2.4.1 AES示例程式碼

#include “ippcp.h”

// use of the CTR mode

int AES_sample(void)

{

   // secret key

   Ipp8u key[] = "\x00\x01\x02\x03\x04\x05\x06\x07"

                 "\x08\x09\x10\x11\x12\x13\x14\x15";

   // define and setup AES cipher

   int ctxSize;

   ippsAESGetSize(&ctxSize);

   IppsAESSpec* pAES = (IppsAESSpec*)( new Ipp8u [ctxSize] );

   ippsAESInit(key, sizeof(key)-1, pAES, ctxSize);

 

   // message to be encrypted

   Ipp8u msg[] = "the quick brown fox jumps over the lazy dog";

   // and initial counter

   Ipp8u ctr0[] = "\xff\xee\xdd\xcc\xbb\xaa\x99\x88"

                  "\x77\x66\x55\x44\x33\x22\x11\x00";

 

   // counter

   Ipp8u ctr[16];

 

   // init counter before encryption

   memcpy(ctr, ctr0, sizeof(ctr));

   // encrypted message

   Ipp8u ctext[sizeof(msg)];

   // encryption

   ippsAESEncryptCTR(msg, ctext, sizeof(msg), pAES, ctr, 64);

 

   // init counter before decryption

   memcpy(ctr, ctr0, sizeof(ctr));

   // decrypted message

   Ipp8u rtext[sizeof(ctext)];

   // decryption

   ippsAESDecryptCTR(ctext, rtext, sizeof(ctext), pAES, ctr, 64);

 

   // remove secret and release resource

   ippsAESInit(0, sizeof(key)-1, pAES, ctxSize);

   delete [] (Ipp8u*)pAES;

 

   int error = memcmp(rtext, msg, sizeof(msg));

   return 0==error;

}

2.4.2 TDES示例程式碼

// Use of the ECB mode

void TDES_sample(void){

      // size of the TDES algorithm block is equal to 8

      const int tdesBlkSize = 8;

     

      // get size of the context needed for the encryption/decryption operation

      int ctxSize;

      ippsDESGetSize(&ctxSize);

      // and allocate one

      IppsDESSpec* pCtx1 = (IppsDESSpec*)( new Ipp8u [ctxSize] );

      IppsDESSpec* pCtx2 = (IppsDESSpec*)( new Ipp8u [ctxSize] );

      IppsDESSpec* pCtx3 = (IppsDESSpec*)( new Ipp8u [ctxSize] );

     

      // define the key

      Ipp8u key1[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

      Ipp8u key2[] = {0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18};

      Ipp8u key3[] = {0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28};

      Ipp8u keyX[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

     

      // and prepare the context for the TDES usage

      ippsDESInit(key1, pCtx1);

      ippsDESInit(key2, pCtx2);

      ippsDESInit(key3, pCtx3);

     

      // define the message to be encrypted

      Ipp8u ptext[] = {"the quick brown fox jumps over the lazy dog"};

      // allocate enough memory for the ciphertext

      // note that

      // the size of ciphertext is always a multiple of the cipher block size

      Ipp8u ctext[(sizeof(ptext)+desBlkSize-1) &~(desBlkSize-1)];

      // encrypt (ECB mode) ptext message

      // pay attention to the 'length' parameter

      // it defines the number of bytes to be encrypted

      ippsTDESEncryptECB(ptext, ctext, sizeof(ctext), pCtx1, pCtx2, pCtx3, IppsCPPaddingNONE);

     

      // allocate memory for the decrypted message

      Ipp8u rtext[sizeof(ctext)];

      // decrypt (ECB mode) ctext message

      // pay attention to the 'length' parameter

      // it defines the number of bytes to be decrypted

      ippsTDESDecryptECB(ctext, rtext, sizeof(ctext), pCtx1, pCtx2, pCtx3, IppsCPPaddingNONE);

     

      // remove actual secret from contexts

      ippsDESInit(keyX, pCtx1);

      ippsDESInit(keyX, pCtx2);

      ippsDESInit(keyX, pCtx3);

      // release resources

      delete (Ipp8u*)pCtx1;

      delete (Ipp8u*)pCtx2;

      delete (Ipp8u*)pCtx3;

}

3. One-Way Hash

待更新。

 

4. Data Authentication

待更新。

 

5. Public Key Cryptography

待更新。

 

6. Finite Field Arithmetic

待更新。

 

附錄A: Support Functions and Classes

略。

附錄B: Removed Functions

略。

 

 

Part III. 實測效率

本章對Intel IPPCP 2018支援的分組密碼演算法AES、TDES、SM4和雜湊演算法SHA1、SHA224、SHA256、SHA384、SHA512、SHA512-224、SHA512-256、SM3、MD5的效率進行測試。

SM2效率待後續更新。

1. 測試平臺

表3.1 測試平臺資訊

測試平臺1

CPU

Intel i7 [email protected],支援AES NI指令

OS

Win7 SP1 64b

記憶體

8G

備註

測試機,安裝Intel IPPCP 2018

測試平臺2

CPU

Intel i3 [email protected],不支援AES NI指令

O