F8和F9用在3G安全中的是机密性算法(f8)和完整性算法(f9),两者都是基于KASUMI算法构造。f8是变形的OFB模式的序列密码;而f9则是变形CBC-MAC模式的消息认证码。
KASUMI算法是日本三菱的Matsui等人基于MISTY算法设计的分组密码。分组大小64bit,密钥长度128bit。由于算法内部大量的使用了16bit的运算,因此最适合16bit处理器实现。
F9产生消息认证码mac。
- F9算法
输入
- COUNT 32 bit Frame dependent input COUNT-I[0]…COUNT-I[31]
- FRESH 32 bit 随机数
- DIRECTION 1 bit
- IK 128bit 完整性密钥 Integrity key IK[0]…IK[127]
- LENGTH * 消息长度
- MESSAGE LENGTH 消息
输出
- MAC 32bit 消息认证码
Step 1 初始化
A = 0 (A是64bit寄存器)
B = 0 (B是64bit寄存器)
KM = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA(128bit)
PS = COUNT || FRESH || MESSAGE || DIRECTION || 10…0(消息填充)
(末尾添加的0的个数为0-63,以保证PS的最后一个分组也是完整的)
记PS = PS0 || PS1 || PS2 || …. || PSBLOCKS-1
Step 2 循环迭代
For(i = 0;i< BLOCKS; i++)
{
}
Step 3 输出MAC
MAC = Left32Bit(B)
F9示意图
- LibTomCrypt与F9
LibTomCrypt中的F9与标准文档中有一定的出入:
- 标准中PS = COUNT || FRESH || MESSAGE || DIRECTION || 10…0(消息填充),而代码中没有这一过程,也就是说调用者需自行组合好消息
- 代码中没有消息填充,或者可以理解为填充的全是零
涉及信息如下:
F9的结构体是
typedef struct {
unsigned char akey[MAXBLOCKSIZE]; // key XOR KM,用于最后一次加密
unsigned char ACC[MAXBLOCKSIZE]; // 标准文档中的寄存器 B
unsigned char IV[MAXBLOCKSIZE]; // 标准文档中的寄存器 A
symmetric_key key;
int cipher;
int buflen;
int keylen;
int blocksize;
} f9_state;
涉及函数
int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
int f9_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) ;
int f9_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) ;
int f9_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen);
int f9_test(void);
──────────────────────────────────────
int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen)
// [功能] 初始化F9
- cipher // [输入] 密码算法
- key // [输入] 密钥
- keylen // [输入] 密钥长度
- f9 // [输入/输出] F9状态
//备注:主要完成 1. 密钥扩展; 2. akey = key XOR 0xA…A; 3. 初始化其他相关参数
──────────────────────────────────────
──────────────────────────────────────
int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen)
// [功能] 处理消息
- in // [输入] 消息
- inlen // [输出] 消息长度
- f9 // [输入/输出] F9状态
//备注: -
──────────────────────────────────────
──────────────────────────────────────
int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
// [功能] 完成F9
- out // [输出] MAC
- outlen // [输入/输出] MAC长度
- f9 // [输入/输出] f9的状态
//备注:-
──────────────────────────────────────
──────────────────────────────────────
int f9_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
// [功能] 处理一段内存消息并输出MAC
- cipher // [输入] 密码算法
- key // [输入] 密钥
- keylen // [输入] 密钥长度
- in // [输入] 消息
- inlen // [输出] 消息长度
- out // [输出] MAC
- outlen // [输入/输出] MAC长度
//备注: 主要是调用f9_process().
──────────────────────────────────────
──────────────────────────────────────
int f9_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...)
// [功能] 处理多段消息并输出MAC
- cipher // [输入] 密码算法
- key // [输入] 密钥
- keylen // [输入] 密钥长度
- in // [输入] 消息
- inlen // [输出] 消息长度
- out // [输出] MAC
- outlen // [输入/输出] MAC长度
//备注: 多段消息以NULL结束,多次调用f9_process().
──────────────────────────────────────
──────────────────────────────────────
int f9_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen);
// [功能] 对文件输出MAC
- cipher // [输入] 密码算法
- key // [输入] 密钥
- keylen // [输入] 密钥长度
- filename // [输入] 文件名
- out // [输出] MAC
- outlen // [输入/输出] MAC长度
//备注: 读文件,然后调用f9_process().
──────────────────────────────────────
──────────────────────────────────────
int f9_test(void);
// [功能] 测试函数
──────────────────────────────────────