密碼庫LibTomCrypt學習記錄——(2.10)分組密碼演算法的工作模式——CTR模式
CTR是對序列號加密後與明文或者密文異或。這種方式被後面的很多工作模式所採用。
參考文獻
- NIST SP 800-38A
- CTR加解密
CTR加密
記每個塊用到的計數器為T1,T2,Tn,要求每個計數器值各不相同
Oj = CIPHK(Tj) for j = 1, 2 … n;
Cj = Pj ⊕ Oj for j = 1, 2 … n-1;
C*n = P*n ⊕ MSBu(On).
CTR解密
Oj = CIPHK(Tj) for j = 1, 2 … n;
Pj = Cj ⊕ Oj for j = 1, 2 … n-1;
P*n = C*n ⊕ MSBu(On).
圖 1 CTR模式
- LibTomCrypt與CTR
LibTomCrypt中與CTR相關的資訊如下:
typedef struct {
int cipher;
int blocklen;
int padlen;
int mode; // 計數器是按大端還是小端存放的,計數器加1時需要
int ctrlen; // 目前讓計數器長度和演算法的分組大小一樣
unsigned char ctr[MAXBLOCKSIZE], // 自增計數器
unsigned char pad[MAXBLOCKSIZE]; // 計數器對應的被加密後的值
symmetric_key key; // 擴充套件金鑰
} symmetric_CTR;
int ctr_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, int ctr_mode, symmetric_CTR *ctr);
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
int ctr_done(symmetric_CTR *ctr);
int ctr_test(void);
注意
按照RFC3686,被加密的Counter Block應該是以下格式
Counter Block(128bit) = Nonce(32bit) || IV(64bit) || BlockCounter(32bit)
BlockCounter為大端表示,從1開始,此後迴圈累加1。
而程式中為簡化操作,採用如下簡單格式
Counter Block(128bit) = IV(128bit)
大端或小端均可。Counter Block每次使用前會加1。
詳細說明
──────────────────────────────────────
int ctr_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, int ctr_mode, symmetric_CTR *ctr)
// [功能] CTR模式初始化
- cipher // [輸入] 密碼演算法索引值
- IV // [輸入] 初始化向量(長度為密碼演算法分組大小)
- Key // [輸入] 金鑰
- keylen // [輸入] 金鑰長度(位元組)
- num_rounds // [輸入] 密碼演算法輪數(建議設定為0,以使用演算法預設輪數)
- ctr_mode // [輸入] CTR模式(IV大端還是小端表示,是否採用RFC3686)
- ctr // [輸出] CTR狀態,含擴充套件金鑰及相關資訊
// [步驟]
1. 呼叫密碼演算法的setup()做密碼擴充套件
2. 呼叫密碼演算法的ecb_encrypt()對計數器ctr進行加密
──────────────────────────────────────
──────────────────────────────────────
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
// [功能] CTR加密
- pt // [輸入] 明文
- ct // [輸出] 密文
- len // [輸入] 明文密文長度
- ctr // [輸出] CTR狀態,含擴充套件金鑰及相關資訊
──────────────────────────────────────
──────────────────────────────────────
int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
// [功能] CTR解密(CTR解密即加密)
- ct // [輸出] 密文
- pt // [輸入] 明文
- len // [輸入] 明文密文長度
- ctr // [輸出] CTR狀態,含擴充套件金鑰及相關資訊
──────────────────────────────────────
──────────────────────────────────────
int ctr_done(symmetric_CTR *ctr);
// [功能] 反初始化(最好能銷燬敏感資訊)
- ctr // [輸入/輸出] CTR狀態,含擴充套件金鑰及相關資訊
──────────────────────────────────────
──────────────────────────────────────
int ctr_test(void);
// [功能] 測試函式
──────────────────────────────────────
──────────────────────────────────────
int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
// [功能] 獲取IV
- IV // [輸出] 初始化向量
- len // [輸出] 初始化向量長度
- ctr // [輸入] CTR狀態,含擴充套件金鑰及相關資訊
──────────────────────────────────────
──────────────────────────────────────
int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
// [功能] 設定IV
- IV // [輸出] 初始化向量
- len // [輸出] 初始化向量長度
- ctr // [輸入] CTR狀態,含擴充套件金鑰及相關資訊
──────────────────────────────────────