F8和F9用在3G安全中的是机密性算法(f8)和完整性算法(f9),两者都是基于KASUMI算法构造。f8是变形的OFB模式的序列密码;而f9则是变形CBC-MAC模式的消息认证码。
KASUMI算法是日本三菱的Matsui等人基于MISTY算法设计的分组密码。分组大小64bit,密钥长度128bit。由于算法内部大量的使用了16bit的运算,因此最适合16bit处理器实现。
F9产生消息认证码mac。
输入
输出
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与标准文档中有一定的出入:
涉及信息如下:
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
//备注:主要完成 1. 密钥扩展; 2. akey = key XOR 0xA…A; 3. 初始化其他相关参数
──────────────────────────────────────
──────────────────────────────────────
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);
// [功能] 完成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
//备注: 主要是调用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
//备注: 多段消息以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
//备注: 读文件,然后调用f9_process().
──────────────────────────────────────
──────────────────────────────────────
int f9_test(void);
// [功能] 测试函数
──────────────────────────────────────