Пример #1
0
void
aes_key_wrap(aes_key_wrap_ctx *ctx, const u_int8_t *P, size_t n, u_int8_t *C)
{
	u_int64_t B[2], t;
	u_int8_t *A, *R;
	size_t i;
	int j;

	memmove(C + 8, P, n * 8);	/* P and C may overlap */
	A = C;				/* A points to C[0] */
	memcpy(A, IV, 8);		/* A = IV, an initial value */

	for (j = 0, t = 1; j <= 5; j++) {
		R = C + 8;
		for (i = 1; i <= n; i++, t++) {
			/* B = A | R[i] */
			memcpy(&B[0], A, 8);
			memcpy(&B[1], R, 8);
			/* B = AES(K, B) */
			rijndael_encrypt(&ctx->ctx, (caddr_t)B, (caddr_t)B);
			/* MSB(64, B) = MSB(64, B) ^ t */
			B[0] ^= htobe64(t);
			/* A = MSB(64, B) */
			memcpy(A, &B[0], 8);
			/* R[i] = LSB(64, B) */
			memcpy(R, &B[1], 8);

			R += 8;
		}
	}
	explicit_bzero(B, sizeof B);
}
Пример #2
0
static void
aes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
{
	u_int8_t block[AES_XTS_BLOCKSIZE];
	u_int i, carry_in, carry_out;

	for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
		block[i] = data[i] ^ ctx->tweak[i];

	if (do_encrypt)
		rijndael_encrypt(&ctx->key1, block, data);
	else
		rijndael_decrypt(&ctx->key1, block, data);

	for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
		data[i] ^= ctx->tweak[i];

	/* Exponentiate tweak */
	carry_in = 0;
	for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
		carry_out = ctx->tweak[i] & 0x80;
		ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
		carry_in = carry_out;
	}
	if (carry_in)
		ctx->tweak[0] ^= AES_XTS_ALPHA;
	bzero(block, sizeof(block));
}
Пример #3
0
static void
pefs_aes_ctr(const rijndael_ctx *aes_ctx, const uint8_t *iv,
             const uint8_t *plaintext, uint8_t *ciphertext, int len)
{
    uint8_t ctr[AES_BLOCK_SIZE];
    uint8_t block[AES_BLOCK_SIZE];
    int l, i;

    if (iv != NULL)
        memcpy(ctr, iv, sizeof(ctr));
    else
        bzero(ctr, sizeof(ctr));

    while (len > 0) {
        rijndael_encrypt(aes_ctx, ctr, block);
        l = (len < AES_BLOCK_SIZE ? len : AES_BLOCK_SIZE);
        for (i = 0; i < l; i++)
            *(ciphertext++) = block[i] ^ *(plaintext++);
        /* Increment counter */
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
            ctr[i]++;
            if (ctr[i] != 0)
                break;
        }
        len -= l;
    }
}
Пример #4
0
static inline void
encrypt(rijndael_ctx *ctx, size_t L, unsigned long counter,
	unsigned char *msg, size_t len,
	unsigned char A[DTLS_CCM_BLOCKSIZE],
	unsigned char S[DTLS_CCM_BLOCKSIZE]) {

  static unsigned long C;

  SET_COUNTER(A, L, counter, C);    
  rijndael_encrypt(ctx, A, S);
  memxor(msg, S, len);
}
Пример #5
0
static inline void
mac(rijndael_ctx *ctx, 
    unsigned char *msg, size_t len,
    unsigned char B[DTLS_CCM_BLOCKSIZE],
    unsigned char X[DTLS_CCM_BLOCKSIZE]) {
  size_t i;

  for (i = 0; i < len; ++i)
    B[i] = X[i] ^ msg[i];

  rijndael_encrypt(ctx, B, X);

}
Пример #6
0
void aes_ecb_encrypt(rijndaelCtx *ctx, uint8_t *data, unsigned len)
{
	unsigned bs = 16;
	uint32_t *d;

	while (len >= bs) {
		d = (uint32_t *)data;
		rijndael_encrypt(ctx, d, d);

		len -= bs;
		data += bs;
	}
}
Пример #7
0
static void
pefs_aesni_encrypt(const struct pefs_session *xses,
    const struct pefs_ctx *xctx, const uint8_t *in, uint8_t *out)
{
	const struct pefs_aesni_ses *ses = &xses->o.ps_aesni;
	const struct pefs_aesni_ctx *ctx = &xctx->o.pctx_aesni;

	if (ses->fpu_saved >= 0)
		aesni_encrypt_ecb(ctx->rounds, ctx->enc_schedule, AES_BLOCK_LEN,
		    in, out);
	else
		rijndael_encrypt(&ctx->sw, in, out);
}
Пример #8
0
static int
docrypt(const unsigned char *key, size_t klen, const unsigned char *in,
    unsigned char *out, size_t len, int do_encrypt)
{
	rijndael_ctx ctx;
	int error = 0;

	memset(&ctx, 0, sizeof(ctx));
	error = rijndael_set_key(&ctx, key, klen * 8);
	if (error)
		return -1;
	if (do_encrypt)
		rijndael_encrypt(&ctx, in, out);
	else
		rijndael_decrypt(&ctx, in, out);
	return 0;
}
Пример #9
0
static int
ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
    LIBCRYPTO_EVP_INL_TYPE len)
{
	struct ssh_rijndael_ctx *c;
	u_char buf[RIJNDAEL_BLOCKSIZE];
	u_char *cprev, *cnow, *plain, *ivp;
	int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;

	if (len == 0)
		return (1);
	if (len % RIJNDAEL_BLOCKSIZE)
		fatal("ssh_rijndael_cbc: bad len %d", len);
	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
		error("ssh_rijndael_cbc: no context");
		return (0);
	}
	if (ctx->encrypt) {
		cnow  = dest;
		plain = (u_char *)src;
		cprev = c->r_iv;
		for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
		    cnow+=RIJNDAEL_BLOCKSIZE) {
			for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
				buf[j] = plain[j] ^ cprev[j];
			rijndael_encrypt(&c->r_ctx, buf, cnow);
			cprev = cnow;
		}
		memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
	} else {
		cnow  = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
		plain = dest+len-RIJNDAEL_BLOCKSIZE;

		memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
		for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
		    plain-=RIJNDAEL_BLOCKSIZE) {
			rijndael_decrypt(&c->r_ctx, cnow, plain);
			ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
			for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
				plain[j] ^= ivp[j];
		}
		memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
	}
	return (1);
}
Пример #10
0
void aes_cbc_encrypt(rijndaelCtx *ctx, uint8_t *iva, uint8_t *data,
                     unsigned len)
{
	uint32_t *iv = (uint32_t *)iva;
	uint32_t *d = (uint32_t *)data;
	unsigned bs = 16;

	while (len >= bs) {
		d[0] ^= iv[0];
		d[1] ^= iv[1];
		d[2] ^= iv[2];
		d[3] ^= iv[3];

		rijndael_encrypt(ctx, d, d);

		iv = d;
		d += bs / 4;
		len -= bs;
	}
}
Пример #11
0
/*
 * Encryption wrapper routines.
 */
static void
aes_xts_reinit(caddr_t key, u_int8_t *iv)
{
	struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
	u_int64_t blocknum;
	u_int i;

	/*
	 * Prepare tweak as E_k2(IV). IV is specified as LE representation
	 * of a 64-bit block number which we allow to be passed in directly.
	 */
	bcopy(iv, &blocknum, AES_XTS_IVSIZE);
	for (i = 0; i < AES_XTS_IVSIZE; i++) {
		ctx->tweak[i] = blocknum & 0xff;
		blocknum >>= 8;
	}
	/* Last 64 bits of IV are always zero */
	bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);

	rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
}
Пример #12
0
void
aes_xts_reinit(caddr_t key, u_int8_t *iv)
{
	struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
#if 0
	u_int64_t blocknum;
	u_int i;
#endif

#if 0
	/*
	 * Prepare tweak as E_k2(IV). IV is specified as LE representation
	 * of a 64-bit block number which we allow to be passed in directly.
	 */
	/* XXX: possibly use htole64? */
#endif
	/* Last 64 bits of IV are always zero */
	bzero(iv + AES_XTS_IV_LEN, AES_XTS_IV_LEN);

	rijndael_encrypt(&ctx->key2, iv, iv);
}
Пример #13
0
Файл: ccm.c Проект: Alpam/casan
static inline void
mac(rijndael_ctx *ctx,
        unsigned char *msg, size_t len,
        unsigned char B[DTLS_CCM_BLOCKSIZE],
        unsigned char X[DTLS_CCM_BLOCKSIZE]) {
    size_t i;

    for (i = 0; i < len; ++i)
        B[i] = X[i] ^ msg[i];

#ifdef NOUVELLE_IMPLE_AES
    // TODO vérifier les tailles des copies
    memcpy(X, B, DTLS_CCM_BLOCKSIZE);
    aes128_enc(X, ctx);
#endif

#ifdef ANCIENNE_IMPLE_AES
    rijndael_encrypt(ctx, B, X);
#endif

}
Пример #14
0
Файл: ccm.c Проект: Alpam/casan
static inline void
encrypt(rijndael_ctx *ctx, size_t L, unsigned long counter,
        unsigned char *msg, size_t len,
        unsigned char A[DTLS_CCM_BLOCKSIZE],
        unsigned char S[DTLS_CCM_BLOCKSIZE]) {

    static unsigned long counter_tmp;

    SET_COUNTER(A, L, counter, counter_tmp);

#ifdef NOUVELLE_IMPLE_AES
    // TODO vérifier les tailles des copies
    memcpy(S, A, DTLS_CCM_BLOCKSIZE);
    aes128_enc(S, ctx);
#endif

#ifdef ANCIENNE_IMPLE_AES
    rijndael_encrypt(ctx, A, S);
#endif
    memxor(msg, S, len);
}
Пример #15
0
int ns_encrypt(u_char *key, u_char *src, u_char *dst, size_t length, size_t key_length) {
  
  if(key_length != 16) {
    ns_log_warning("rijndael key_length != 16 which will likely lead to an Bus error or "
        "segmentation fault!");
  }
  
  if(length % NS_BLOCK_SIZE != 0) {
    ns_log_warning("The length of the src must be a multiple of NS_BLOCK_SIZE "
    "(which is %d) but is %d.", NS_BLOCK_SIZE, length);
  }
  
  rijndael_ctx ctx;
  rijndael_set_key(&ctx, key, 8 * key_length);
  
  int j;
  
  // Encrypt blockwise from src to dst.
  for(j = 0; j < length; j += NS_BLOCK_SIZE) { 
    rijndael_encrypt(&ctx, &(src[j]), &(dst[j])); 
  }
  
  return 0;
}
//===========================================================================
// スレッド実行
//===========================================================================
void __fastcall TAttacheCaseFileEncrypt::Execute()
{

int i, c;
int res;

float ProgressPercentNumF;  //進捗パーセンテージ(浮動小数点)

z_stream z;                 // zlibライブラリとやりとりするための構造体
int flush, status;          // zlib

//出力する暗号化ファイルのタイムスタンプを元ファイルに合わせる
HANDLE hFile;
//_WIN32_FIND_DATAW first_fd;
ZeroMemory(&first_fd, sizeof(_WIN32_FIND_DATAW));

int len, pos;
int FileIndex;
String FilePath;

int HeaderSize;                          //ヘッダデータサイズ
__int64 CurrentDriveFreeSpaceSize = -1;  //保存するドライブの空き容量

//実行可能形式出力ファイルのデータサイズ
__int64 ExeAllSize = 0;
__int64 ExeSize    = 0;

//全体のファイルサイズ
AllTotalSize = 0;
__int64 TotalSize = 0;

//バッファ
char source_buffer[BUF_SIZE];
char read_buffer[BUF_SIZE];
char out_buffer[BUF_SIZE];
char chain_buffer[BUF_SIZE]; // IVなどを格納するチェインバッファ
char margin_buffer[BUF_SIZE];

//ファイルストリーム
TFileStream *fsIn;
TFileStream *fsOut;
TFileStream *fsExe;

//オープン中か
bool fOpenIn;
bool fOpenOut;
//メモリストリーム
TMemoryStream *pms = new TMemoryStream;

// マージンバッファサイズ
int MarginBufSize = MARGIN_BUF_SIZE;

// PKCS #7 Pading num.
unsigned char paddingNum = 0;

//---------------------------------------
// 同名ファイルがあるのでダイアログ表示
//---------------------------------------
if ( fConfirmOverwirte == true && fOverwirteYesToAll == false ) {

	if (FileExists(OutFilePath) == true) {
		//同名ファイルの上書き確認メッセージダイアログ
		MsgText = LoadResourceString(&Msgencrypt::_MSG_CONFIRM_OVER_WRITE_SAME_FILE)+"\n"+OutFilePath;
		Synchronize(&PostConfirmOverwriteMessageForm);
		if ( MsgReturnVal == mrYes ) {
			//上書きOKなのでFilePathはそのまま
		}
		else if ( MsgReturnVal == mrNo ) {
			//別名保存でFilePath文字列が書き換えられてきている
			OutFilePath = MsgReturnPath;
		}
		else if ( MsgReturnVal == mrYesToAll ) {
			//すべて上書き(YesToAll)
			fOverwirteYesToAll = true;
		}
		else if ( MsgReturnVal == mrCancel ) {
			//キャンセル
			delete pms;
			goto LabelStop;
		}
	}

}

//---------------------------------------
// ヘッダ情報の生成&ファイル総サイズ取得
//---------------------------------------

//'暗号化するファイルリストの生成中...'
ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_LISTING);

if ( CreateHeaderData( pms, InputFileList, FilePathList, AllTotalSize) == false ){
	if (Terminated == true) {
		//ユーザーキャンセルで抜けてきた
		delete pms;
		goto LabelStop;
	}
	else{
		//'暗号化するファイルを開けません。他のアプリケーションが使用中の可能性があります。'
		MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_FILE_OPEN);
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
		delete pms;
		goto LabelError;
	}

}

//-----------------------------------
// ディスクの空き容量チェック
//-----------------------------------

CurrentDriveFreeSpaceSize = GetDiskFreeSpaceNum(OutFilePath);

if (CurrentDriveFreeSpaceSize > -1 ) {
	if ( AllTotalSize > CurrentDriveFreeSpaceSize ) {
		//"ディスクの空き容量が足りません! 暗号化ファイルを保存できません。\n
		//暗号化を中止します。;"
		MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_NO_DISK_FREE_SPACE);
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
		delete pms;
		goto LabelError;
	}
}
else{
	// -1はネットワークドライブの可能性があるので無視
	//(万が一、別のエラーの場合、実際書き込みに移行したときエラーが発生する)
}

//-----------------------------------
// 実行可能形式でかつ
// 合計バイト数が4GBを越えたときのエラー
//-----------------------------------
if ( fExeOutputOption == true && fOver4gbOk == false && AllTotalSize > SIZE_4GB ){

	//実行形式ファイルのサイズが4GBを超えてしまう可能性があります!\n
	//Win32アプリケーションとして実行できなくなるかもしれませんがよろしいですか?';
	MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OVER_4GB_EXE);
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbYes << mbNo;
	MsgDefaultButton = mbNo;
	Synchronize(&PostConfirmMessageForm);

	if ( MsgReturnVal == mbNo) {
		//キャンセル
		delete pms;
		goto LabelStop;
	}

}

//-----------------------------------
// 暗号化ファイルの生成開始
//-----------------------------------
//'暗号化しています...'
ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ENCRYPTING);
ProgressMsgText = ExtractFileName(OutFilePath);

TotalSize = 0;

try{
	fsOut = new TFileStream(OutFilePath, fmCreate);
	fOpenOut = true;
}
catch(...){
	//'保存する先のファイルが開けません。他のアプリケーションが使用中の可能性があります。'
	MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_OPEN) + "\n" + OutFilePath;
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	delete pms;
	goto LabelError;
}

//-----------------------------------
// 実行可能形式の出力
//-----------------------------------
if ( fExeOutputOption == true ){

	//-----------------------------------
	// 自分のお尻から実行データを抽出
	//-----------------------------------

	//自分自身の実行ファイルを開く
	try{
		fsExe = new TFileStream(Application->ExeName, fmOpenRead | fmShareDenyWrite);
	}
	catch(...){
		//'実行可能形式出力に失敗しました。暗号化処理を中止します。'
		MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_EXEOUT_FAILED);
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
		delete pms;
		goto LabelError;
	}

	//切り出すサイズを取得
	fsExe->Seek(-(__int64)sizeof(__int64), TSeekOrigin::soEnd);
	fsExe->Read(&ExeAllSize, sizeof(__int64));

	//処理する合計サイズに実行形式分を加える
	AllTotalSize += ExeAllSize;

	//自己実行可能形式データの境界へ
	fsExe->Seek(-(__int64)ExeAllSize-sizeof(__int64), TSeekOrigin::soEnd);

	while(fsExe->Read(read_buffer, BUF_SIZE) != 0 ){
		ExeSize+=BUF_SIZE;
		//書き込む
		if ( ExeSize < ExeAllSize ){
			fsOut->Write(read_buffer, BUF_SIZE);
			TotalSize += BUF_SIZE;
		}
		else{
			fsOut->Write(read_buffer, ExeSize-ExeAllSize);
			TotalSize += (ExeSize-ExeAllSize);
		}
		//進捗表示
		ProgressPercentNumF = (float)TotalSize/AllTotalSize;
		ProgressPercentNum = (int)(ProgressPercentNumF*100);
		if (AllTotalSize < 104857600) {	// 100MB未満
			ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%";
		}
		else{
			ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%";
		}
	}
	//自分自身を閉じる
	delete fsExe;
}

//-----------------------------------
// ヘッダ情報の描き込み
//-----------------------------------

pms->SaveToStream(fsOut);	//fsOutに追記
delete pms;


//-----------------------------------
// Rijndaelの初期化
//-----------------------------------

gentables();

gkey( 8, 8, key);

// 初期化ベクトルを生成して先頭に書き込む
fillrand(chain_buffer, BUF_SIZE);

if ( fsOut->Write(chain_buffer, BUF_SIZE) < BUF_SIZE ){
	//''保存先に指定された暗号化ファイルに書き込めません。
	MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath;
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	goto LabelError;
}

//-----------------------------------
// zlib 初期化(圧縮においてすべてのメモリ管理をライブラリに任せる)
z.zalloc = Z_NULL;
z.zfree  = Z_NULL;
z.opaque = Z_NULL;
//z.next_in = Z_NULL;

// 第2引数は圧縮の度合。0~9 の範囲の整数で,0 は無圧縮
// Z_DEFAULT_COMPRESSION (= 6) が標準

if (deflateInit(&z, CompressRateNum) != Z_OK){
	//zlibエラー表示はラベル先で
	goto LabelError;
}

//出力バッファの初期化
for(i = 0; i < BUF_SIZE; i++){
	out_buffer[i] = 0;
}

// zlibに入出力バッファをセットする
z.avail_in  = 0;                    // 入力バッファ中のデータのバイト数
z.next_out  = out_buffer;           // 出力バッファ残量
z.avail_out = BUF_SIZE;             // 出力ポインタ

// 通常は deflate() の第2引数は Z_NO_FLUSH にして呼び出す
flush = Z_NO_FLUSH;

FileIndex = 0;

while(!Terminated) {

	//-----------------------------------
	//入力
	//-----------------------------------
	if ( z.avail_in == 0 && flush != Z_FINISH){

		pos = 0;

		for(i = 0; i < BUF_SIZE; i++){
			source_buffer[i] = 0;
			read_buffer[i] = 0;
		}

		while ( pos < BUF_SIZE ){

			//オープン中のファイルがあればそこから読む
			if ( fOpenIn == true ) {

				if (pos < BUF_SIZE) {

					len = fsIn->Read(read_buffer, BUF_SIZE - pos);
					TotalSize+=len;

					for (i = 0; i < len; i++) {
						source_buffer[pos+i] = read_buffer[i];
					}

					if (len < BUF_SIZE - pos) {
						fOpenIn = false; //ファイルを閉じる
						delete fsIn;
					}

				}

				pos += len;

			}
			//ファイルを開く
			else{
				if (FileIndex < FilePathList->Count) {
					while(FileIndex < FilePathList->Count){
						if (FilePathList->Strings[FileIndex] != "") {
							try{
								fsIn = new TFileStream(FilePathList->Strings[FileIndex], fmOpenRead | fmShareDenyWrite);
								fOpenIn = true;
								FileIndex++;
								break;
							}
							catch(...){
								//'暗号化するファイルを開けません。他のアプリケーションが使用中の可能性があります。'
								MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_FILE_OPEN);
								MsgType = mtError;
								MsgButtons = TMsgDlgButtons() << mbOK;
								MsgDefaultButton = mbOK;
								Synchronize(&PostConfirmMessageForm);
								fOpenIn = false;
								goto LabelError;
							}
						}
						FileIndex++;
					}
				}
				else{

					//読み込むファイルがなくなったので、
					//お尻にダミーのマージンデータを挿入する
					//
					//【補足】
					// 本来はここにあるマージンデータ挿入処理は不要ですが、
					// 昔に作った際に復号の際に圧縮データ境界のチェックを
					// 怠っていたため、このように余分なデータを
					// 入れておくという力業を使っています(すみません...)
					fillrand(margin_buffer, BUF_SIZE);

					for (i = pos; i < BUF_SIZE; i++) {
						source_buffer[i] = margin_buffer[i];
					}

					pos = BUF_SIZE;
					MarginBufSize -= BUF_SIZE;

				}//end if (FileIndex < FilePathList->Count);

			}//end if ( fOpenIn == true );

		}//while ( pos < BUF_SIZE && 0 < MarginBufSize );

		if (MarginBufSize < 1) {
			flush = Z_FINISH;	//入力バッファはこれが最後
		}

		z.next_in = source_buffer;
		z.avail_in = pos;

	}//end if ( z.avail_in == 0 );

	//-----------------------------------
	//圧縮
	//-----------------------------------
	if ( z.avail_out > 0 ){
		status = deflate(&z, flush);
	}
	if (status == Z_STREAM_END){
			break;
	}
	if (status != Z_OK ){
		//#define Z_OK              0
		//#define Z_STREAM_END      1
		//#define Z_NEED_DICT       2
		//#define Z_ERRNO         (-1)
		//#define Z_STREAM_ERROR  (-2)
		//#define Z_DATA_ERROR    (-3)
		//#define Z_MEM_ERROR     (-4)
		//#define Z_BUF_ERROR     (-5)
		//#define Z_VERSION_ERROR (-6)
		goto LabelError;
	}
	//-----------------------------------
	//出力
	//-----------------------------------
	if ( z.avail_out == 0 ){

		// CBC - xor the file bytes with the IV bytes
		for(i = 0; i < BUF_SIZE; i++){
			out_buffer[i] ^= chain_buffer[i];
		}

		//encrypt!
		rijndael_encrypt(out_buffer);

		len = fsOut->Write(out_buffer, BUF_SIZE);

		if (len < BUF_SIZE) {
			//'保存先に指定された暗号化ファイルに書き込めません。
			MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath;
			MsgType = mtError;
			MsgButtons = TMsgDlgButtons() << mbOK;
			MsgDefaultButton = mbOK;
			Synchronize(&PostConfirmMessageForm);
			goto LabelError;
		}

		for(i = 0; i < BUF_SIZE; i++){
			chain_buffer[i] = out_buffer[i];
			out_buffer[i] = 0;
		}

		z.next_out = out_buffer;    // 出力バッファ残量を元に戻す
		z.avail_out = BUF_SIZE;     // 出力ポインタを元に戻す

	}

	//-----------------------------------
	//進捗状況表示

	if (AllTotalSize == 0) {
		ProgressPercentNum = 100;
		ProgressPercentNumText = "100%";
	}
	else if (TotalSize == 0) {
		ProgressPercentNum = 0;
		ProgressPercentNumText = "0%";
	}
	else{
		ProgressPercentNumF = (float)TotalSize/AllTotalSize;
		ProgressPercentNum = (int)(ProgressPercentNumF*100);

		if (AllTotalSize < 104857600) {	// 100MB未満
			ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%";
		}
		else{
			ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%";
		}
	}
	//-----------------------------------

	if ( fOpenIn == true ){
		ProgressMsgText = ExtractFileName(fsIn->FileName);
	}
	else{
		ProgressMsgText = ExtractFileName(OutFilePath);
	}


}//while(!Terminated);

if (Terminated == true) {
	//ユーザーキャンセルで抜けてきた
	goto LabelStop;
}

//残りのバッファ
if (z.avail_out > 0) {

		// PKCS #7 パディング
		len = BUF_SIZE - z.avail_out;

		paddingNum = (char)z.avail_out;
		for(i = len; i < BUF_SIZE; i++){
			out_buffer[i] = paddingNum;
		}

		// CBC - xor the file bytes with the IV bytes
		for(i = 0; i < BUF_SIZE; i++){
			out_buffer[i] ^= chain_buffer[i];
		}

		//encrypt!
		rijndael_encrypt(out_buffer);

		if ((len = fsOut->Write(out_buffer, BUF_SIZE)) != BUF_SIZE){
			//'保存先に指定された暗号化ファイルに書き込めません。
			MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath;
			MsgType = mtError;
			MsgButtons = TMsgDlgButtons() << mbOK;
			MsgDefaultButton = mbOK;
			Synchronize(&PostConfirmMessageForm);
			goto LabelError;
		}

}

if (deflateEnd(&z) != Z_OK){
	//zlibエラー
	goto LabelError;
}


//-----------------------------------
// 実行可能形式ファイルは
// 末尾へ暗号化データサイズを書き込む
//-----------------------------------
if ( fExeOutputOption == true ){
	ExeSize = fsOut->Seek((__int64)0, TSeekOrigin::soEnd);
	ExeSize = ExeSize-ExeAllSize;
	fsOut->Write(&ExeSize, sizeof(__int64));
}

//-----------------------------------
// 完了
//-----------------------------------
ProgressPercentNum = 100;
//'完了'
ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_COMPLETE);
ProgressMsgText = ExtractFileName(OutFilePath);

if (fOpenIn == true) {
	delete fsIn;
}
if (fOpenOut == true) {
	delete fsOut;
}

//出力する暗号化ファイルのタイムスタンプを元ファイルに合わせる
if ( fKeepTimeStamp == true && first_fd.cFileName[0] != NULL ) {

	hFile = CreateFileW(FilePath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if (hFile != INVALID_HANDLE_VALUE) {
		SetFileTime( hFile, &first_fd.ftCreationTime, &first_fd.ftLastAccessTime, &first_fd.ftLastWriteTime);
		CloseHandle(hFile);
	}
}

StatusNum = 1;
return;

//-----------------------------------
// エラーの後始末
//-----------------------------------
LabelError:

	ProgressPercentNum = 0;

	if ( status < 0 ){
		//'zlibライブラリからエラーを返されました。'
		//'エラー番号:'
		MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_ZLIB) + IntToStr(status) + "\n" + z.msg;
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
	}

	//'エラー'
	ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ERROR);
	//'暗号化に失敗しました。'
	ProgressMsgText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_DETAIL_FAILED);

	if (fOpenIn == true) {
		delete fsIn;
	}
	if (fOpenOut == true) {
		delete fsOut;
	}

	StatusNum = -1;

	return;


//-----------------------------------
// ユーザーキャンセルの後始末
//-----------------------------------
LabelStop:

	ProgressPercentNum = 0;
	//'キャンセル'
	ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_USER_CANCEL);
	//'暗号化が中止されました。'
	ProgressMsgText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_DETAIL_STOPPED);

	if (fOpenIn == true) {
		delete fsIn;
	}
	if (fOpenOut == true) {
		delete fsOut;
	}

	StatusNum = -2;

	return;

}
Пример #17
0
long int
dtls_ccm_decrypt_message(rijndael_ctx *ctx, size_t M, size_t L,
			 unsigned char N[DTLS_CCM_BLOCKSIZE], 
			 unsigned char *msg, size_t lm, 
			 const unsigned char *aad, size_t la) {
  
  size_t len;
  unsigned long C;
  unsigned long counter = 1; /* \bug does not work correctly on ia32 when
			             lm >= 2^16 */
  unsigned char A[DTLS_CCM_BLOCKSIZE]; /* A_i blocks for encryption input */
  unsigned char B[DTLS_CCM_BLOCKSIZE]; /* B_i blocks for CBC-MAC input */
  unsigned char S[DTLS_CCM_BLOCKSIZE]; /* S_i = encrypted A_i blocks */
  unsigned char X[DTLS_CCM_BLOCKSIZE]; /* X_i = encrypted B_i blocks */

  if (lm < M)
    goto error;

  len = lm;	      /* save original length */
  lm -= M;	      /* detract MAC size*/

  /* create the initial authentication block B0 */
  block0(M, L, la, lm, N, B);
  add_auth_data(ctx, aad, la, B, X);

  /* initialize block template */
  A[0] = L-1;

  /* copy the nonce */
  memcpy(A + 1, N, DTLS_CCM_BLOCKSIZE - L);
  
  while (lm >= DTLS_CCM_BLOCKSIZE) {
    /* decrypt */
    encrypt(ctx, L, counter, msg, DTLS_CCM_BLOCKSIZE, A, S);
    
    /* calculate MAC */
    mac(ctx, msg, DTLS_CCM_BLOCKSIZE, B, X);

    /* update local pointers */
    lm -= DTLS_CCM_BLOCKSIZE;
    msg += DTLS_CCM_BLOCKSIZE;
    counter++;
  }

  if (lm) {
    /* decrypt */
    encrypt(ctx, L, counter, msg, lm, A, S);

    /* Calculate MAC. Note that msg ends in the MAC so we must
     * construct B to contain X ^ msg for the first lm bytes (done in
     * mac() and X ^ 0 for the remaining DTLS_CCM_BLOCKSIZE - lm bytes
     * (i.e., we can use memcpy() here).
     */
    memcpy(B + lm, X + lm, DTLS_CCM_BLOCKSIZE - lm);
    mac(ctx, msg, lm, B, X); 

    /* update local pointers */
    msg += lm;
  }
  
  /* calculate S_0 */  
  SET_COUNTER(A, L, 0, C);
  rijndael_encrypt(ctx, A, S);

  memxor(msg, S, M);

  /* return length if MAC is valid, otherwise continue with error handling */
  if (memcmp(X, msg, M) == 0) 
    return len - M;
  
 error:
  return -1;
}
//===========================================================================
// ヘッダ情報を生成する
//===========================================================================
bool __fastcall TAttacheCaseFileEncrypt::CreateHeaderData
	(TMemoryStream *pms, TStringList *FileList, TStringList *FilePathList, __int64 &AllTotalFileSize)
{

int i, c;

int ret;
int Index = 0;
int HeaderSizeAddress = 0;
TSearchRec sr;
String OneLine;
String DirPath, FileName;

String MsgText;

//暗号部トークン
const AnsiString Passcode_AttacheCase = "Passcode:AttacheCase\n";
//暗号化ファイルの作成日
AnsiString LastDateTimeString = "LastDateTime:" + DateTimeToStr(Now()) + "\n";

//旧ヘッダーテキストすべて
AnsiString Fn_HeaderText;
//Unicode用ヘッダーテキストすべて
String U_HeaderText;

int EncryptHeaderSize = 0;  //暗号部ヘッダサイズ

char buffer[BUF_SIZE];
char chain_buffer[BUF_SIZE];

TStringList *HeaderDataList;
TMemoryStream* tpms;          //テンポラリメモリストリーム

//-----------------------------------
// ヘッダ情報(平文)
//-----------------------------------
const char charReservedValue[4] = { 0, 0, 0, 0 };

const char charDataSubVersion = ATC_DATA_SUB_VERSION;
const char charOptMissTypeLimitsNumOption = intOptMissTypeLimitsNumOption;
const char charOptBrokenFileOption = (fOptBrokenFileOption > 0 ? 1 : 0);
const char charTokenString[17] = "_AttacheCaseData";
const int DataFileVersion = ATC_DATA_FILE_VERSION;
const int AlgorismType = TYPE_ALGORISM_RIJNDAEL;

//データサブバージョン                              : 1byte
pms->Write(&charDataSubVersion, sizeof(char));
//予約データ(reserved)                             : 1byte
pms->Write(&charReservedValue, sizeof(char));
//ミスタイプ回数                                    : 1byte
pms->Write(&charOptMissTypeLimitsNumOption, sizeof(char));
//破壊するか否か                                    : 1byte
pms->Write(&charOptBrokenFileOption, sizeof(char));
//トークン                                          : 16byte
pms->Write(&charTokenString, 16);
//データファイルバージョン                          : 4byte
pms->Write(&DataFileVersion, sizeof(int));
//アルゴリズムタイプ                                : 4byte
pms->Write(&AlgorismType, sizeof(int));
//暗号化部分のヘッダデータサイズ(先に確保しておく):4byte
HeaderSizeAddress = pms->Position;
pms->Write(&EncryptHeaderSize, sizeof(int));

//-----------------------------------
// ヘッダ情報(暗号化部分)
//-----------------------------------

//進捗状況表示
ProgressPercentNum = -1;
//'暗号化するファイルリストの生成中...'
ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_LISTING);

//ヘッダデータリスト(文字列)
HeaderDataList = new TStringList;
//パスワード
HeaderDataList->Add(Passcode_AttacheCase);
//作成日
HeaderDataList->Add(LastDateTimeString);

for ( i = 0; i < FileList->Count; i++ ){
	//ファイル
	if (FileExists(FileList->Strings[i]) == true) {
		DirPath = ExtractFileDir(FileList->Strings[i]);
		FileName = ExtractFileName(FileList->Strings[i]);
		ProgressMsgText = FileName;      //処理中のファイル名
		AllTotalFileSize +=
			GetFileInfoList(Index, DirPath, FileName, FileList->Strings[i], FilePathList, HeaderDataList);
	}
	//ディレクトリ
	else{
		DirPath = ExtractFileDir(FileList->Strings[i]);
		FileName = ExtractFileName(FileList->Strings[i]);
		ProgressMsgText = FileName;      //処理中のファイル名
		//トップディレクトリ
		GetFileInfoList(Index, DirPath, FileName, FileList->Strings[i], FilePathList, HeaderDataList);
		//その配下
		AllTotalFileSize +=
			GetFileInfoList(Index, FileList->Strings[i], "", FileList->Strings[i], FilePathList, HeaderDataList);
	}

	//ユーザーキャンセル
	if (Terminated == true) {
		delete HeaderDataList;
		return(false);
	}

}// end for;

//進捗状況表示
ProgressPercentNum = -1;
//'ヘッダデータを書き込んでいます...'
ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ENCRYPTING_LIST);
ProgressMsgText = "";

//メモリストリームへ書き込み
tpms = new TMemoryStream;

//------------------------------------------------
// 暗号化時にヘッダデータの互換性維持
//---------------------------------------------------
HeaderDataList->SaveToStream(tpms, TEncoding::GetEncoding(932));
//新バージョン(ver.2.8.0~)用(UTF-8)に保存
for (i = 0; i < HeaderDataList->Count; i++) {
	HeaderDataList->Strings[i] = StringReplace(HeaderDataList->Strings[i],"Fn_","U_",TReplaceFlags()<<rfIgnoreCase );
}
HeaderDataList->SaveToStream(tpms, TEncoding::UTF8);

delete HeaderDataList;

//-----------------------------------
//ヘッダ情報の暗号化
//-----------------------------------

//暗号化の準備
gentables();
//キー入力
gkey( 8, 8, key);

for (i = 0; i < BUF_SIZE; i++) {
	buffer[i] = 0;
}

//初期化ベクトル(IV)を生成
fillrand(chain_buffer, BUF_SIZE);
pms->Write(chain_buffer, BUF_SIZE);

//先頭にポインタを戻す
tpms->Seek((__int64)0, TSeekOrigin::soBeginning);
EncryptHeaderSize = 0;

//CBCモードで書き込む
while (tpms->Read( buffer, BUF_SIZE ) != NULL){

	EncryptHeaderSize += BUF_SIZE;

	// xor
	for ( i = 0; i < BUF_SIZE; i++ ){
		buffer[i] ^= chain_buffer[i];
	}

	// rijndael
	rijndael_encrypt(buffer);

	pms->Write(buffer, BUF_SIZE);

	//CBC&バッファの初期化
	for ( i = 0; i < BUF_SIZE; i++ ){
		chain_buffer[i] = buffer[i];
		buffer[i] = 0;
	}

	//ユーザーキャンセル
	if (Terminated == true) {
		delete tpms;
		return(false);
	}

}//loop;

delete tpms;

//暗号化部分のヘッダデータサイズ(確保しておいた場所へ改めて書き込む)
pms->Position = HeaderSizeAddress;
pms->Write(&EncryptHeaderSize, sizeof(int));
//先頭にポインタを戻す
pms->Seek((__int64)0, TSeekOrigin::soBeginning);

return(true);


}//end CreateHeaderData;
Пример #19
0
struct iob_s *ieee80211_ccmp_decrypt(struct ieee80211_s *ic, struct iob_s *iob0,
                                     struct ieee80211_key *k)
{
  struct ieee80211_ccmp_ctx *ctx = k->k_priv;
  struct ieee80211_frame *wh;
  uint64_t pn, *prsc;
  const uint8_t *ivp;
  const uint8_t *src;
  uint8_t *dst;
  uint8_t mic0[IEEE80211_CCMP_MICLEN];
  uint8_t a[16];
  uint8_t b[16];
  uint8_t s0[16];
  uint8_t s[16];
  struct iob_s *next0;
  struct iob_s *iob;
  struct iob_s *next;
  int hdrlen;
  int left;
  int moff;
  int noff;
  int len;
  uint16_t ctr;
  int i;
  int j;

  wh = (FAR struct ieee80211_frame *)IOB_DATA(iob0);
  hdrlen = ieee80211_get_hdrlen(wh);
  ivp = (uint8_t *) wh + hdrlen;

  if (iob0->io_pktlen < hdrlen + IEEE80211_CCMP_HDRLEN + IEEE80211_CCMP_MICLEN)
    {
      iob_free_chain(iob0);
      return NULL;
    }

  /* Check that ExtIV bit is set */

  if (!(ivp[3] & IEEE80211_WEP_EXTIV))
    {
      iob_free_chain(iob0);
      return NULL;
    }

  /* Retrieve last seen packet number for this frame type/priority */

  if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
    {
      uint8_t tid =
        ieee80211_has_qos(wh) ? ieee80211_get_qos(wh) & IEEE80211_QOS_TID : 0;
      prsc = &k->k_rsc[tid];
    }
  else
    {
      /* 11w: management frames have their own counters */

      prsc = &k->k_mgmt_rsc;
    }

  /* Extract the 48-bit PN from the CCMP header */

  pn = (uint64_t) ivp[0] |
    (uint64_t) ivp[1] << 8 |
    (uint64_t) ivp[4] << 16 |
    (uint64_t) ivp[5] << 24 | (uint64_t) ivp[6] << 32 | (uint64_t) ivp[7] << 40;

  if (pn <= *prsc)
    {
      /* Replayed frame, discard */

      iob_free_chain(iob0);
      return NULL;
    }

  next0 = iob_alloc(false);
  if (next0 == NULL)
    {
      goto nospace;
    }

  if (iob_clone(next0, iob0) < 0)
    {
      goto nospace;
    }

  next0->io_pktlen -= IEEE80211_CCMP_HDRLEN + IEEE80211_CCMP_MICLEN;
  next0->io_len = CONFIG_IEEE80211_BUFSIZE;
  if (next0->io_len > next0->io_pktlen)
    {
      next0->io_len = next0->io_pktlen;
    }

  /* Construct initial B, A and S_0 blocks */

  ieee80211_ccmp_phase1(&ctx->rijndael, wh, pn,
                        next0->io_pktlen - hdrlen, b, a, s0);

  /* Copy 802.11 header and clear protected bit */

  memcpy(IOB_DATA(next0), wh, hdrlen);
  wh = (FAR struct ieee80211_frame *)IOB_DATA(next0);
  wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;

  /* construct S_1 */
  ctr = 1;
  a[14] = ctr >> 8;
  a[15] = ctr & 0xff;
  rijndael_encrypt(&ctx->rijndael, a, s);

  /* decrypt frame body and compute MIC */
  j = 0;
  iob = iob0;
  next = next0;
  moff = hdrlen + IEEE80211_CCMP_HDRLEN;
  noff = hdrlen;
  left = next0->io_pktlen - noff;
  while (left > 0)
    {
      if (moff == iob->io_len)
        {
          /* Nothing left to copy from iob */

          iob = iob->io_flink;
          moff = 0;
        }

      if (noff == next->io_len)
        {
          struct iob_s *newbuf;

          /* next is full and there's more data to copy */

          newbuf = iob_alloc(false);
          if (newbuf == NULL)
            {
              goto nospace;
            }

          next->io_flink = newbuf;
          next = newbuf;
          next->io_len = 0;

          if (next->io_len > left)
            {
              next->io_len = left;
            }

          noff = 0;
        }

      len = MIN(iob->io_len - moff, next->io_len - noff);

      src = (FAR uint8_t *) IOB_DATA(iob) + moff;
      dst = (FAR uint8_t *) IOB_DATA(next) + noff;

      for (i = 0; i < len; i++)
        {
          /* decrypt message */

          dst[i] = src[i] ^ s[j];

          /* update MIC with clear text */

          b[j] ^= dst[i];
          if (++j < 16)
            continue;
          /* we have a full block, encrypt MIC */

          rijndael_encrypt(&ctx->rijndael, b, b);

          /* construct a new S_ctr block */

          ctr++;
          a[14] = ctr >> 8;
          a[15] = ctr & 0xff;
          rijndael_encrypt(&ctx->rijndael, a, s);
          j = 0;
        }

      moff += len;
      noff += len;
      left -= len;
    }

  if (j != 0)
    {
      /* Partial block, encrypt MIC */

      rijndael_encrypt(&ctx->rijndael, b, b);
    }

  /* Finalize MIC, U := T XOR first-M-bytes( S_0 ) */

  for (i = 0; i < IEEE80211_CCMP_MICLEN; i++)
    b[i] ^= s0[i];

  /* Check that it matches the MIC in received frame */

  iob_copyout(mic0, iob, moff, IEEE80211_CCMP_MICLEN);
  if (memcmp(mic0, b, IEEE80211_CCMP_MICLEN) != 0)
    {
      iob_free_chain(iob0);
      iob_free_chain(next0);
      return NULL;
    }

  /* update last seen packet number (MIC is validated) */
  *prsc = pn;

  iob_free_chain(iob0);
  return next0;

nospace:
  iob_free_chain(iob0);
  if (next0 != NULL)
    {
      iob_free_chain(next0);
    }

  return NULL;
}
Пример #20
0
struct iob_s *ieee80211_ccmp_encrypt(struct ieee80211_s *ic, struct iob_s *iob0,
                                     struct ieee80211_key *k)
{
  struct ieee80211_ccmp_ctx *ctx = k->k_priv;
  const struct ieee80211_frame *wh;
  const uint8_t *src;
  uint8_t *ivp, *mic, *dst;
  uint8_t a[16], b[16], s0[16], s[16];
  struct iob_s *next0, *iob, *next;
  int hdrlen, left, moff, noff, len;
  uint16_t ctr;
  int i, j;

  next0 = iob_alloc(false);
  if (next0 == NULL)
    {
      goto nospace;
    }

  if (iob_clone(next0, iob0) < 0)
    {
      goto nospace;
    }

  next0->io_pktlen += IEEE80211_CCMP_HDRLEN;
  next0->io_len = CONFIG_IEEE80211_BUFSIZE;

  if (next0->io_len > next0->io_pktlen)
    {
      next0->io_len = next0->io_pktlen;
    }

  /* Copy 802.11 header */

  wh = (FAR struct ieee80211_frame *)IOB_DATA(iob0);
  hdrlen = ieee80211_get_hdrlen(wh);
  memcpy(IOB_DATA(next0), wh, hdrlen);

  k->k_tsc++;                   /* increment the 48-bit PN */

  /* construct CCMP header */

  ivp = (FAR uint8_t *) IOB_DATA(next0) + hdrlen;
  ivp[0] = k->k_tsc;            /* PN0 */
  ivp[1] = k->k_tsc >> 8;       /* PN1 */
  ivp[2] = 0;                   /* Rsvd */
  ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;  /* KeyID | ExtIV */
  ivp[4] = k->k_tsc >> 16;      /* PN2 */
  ivp[5] = k->k_tsc >> 24;      /* PN3 */
  ivp[6] = k->k_tsc >> 32;      /* PN4 */
  ivp[7] = k->k_tsc >> 40;      /* PN5 */

  /* construct initial B, A and S_0 blocks */
  ieee80211_ccmp_phase1(&ctx->rijndael, wh, k->k_tsc,
                        iob0->io_pktlen - hdrlen, b, a, s0);

  /* construct S_1 */
  ctr = 1;
  a[14] = ctr >> 8;
  a[15] = ctr & 0xff;
  rijndael_encrypt(&ctx->rijndael, a, s);

  /* encrypt frame body and compute MIC */
  j = 0;
  iob = iob0;
  next = next0;
  moff = hdrlen;
  noff = hdrlen + IEEE80211_CCMP_HDRLEN;
  left = iob0->io_pktlen - moff;
  while (left > 0)
    {
      if (moff == iob->io_len)
        {
          /* Nothing left to copy from iob */

          iob = iob->io_flink;
          moff = 0;
        }

      if (noff == next->io_len)
        {
          struct iob_s *newbuf;

          /* next is full and there's more data to copy */

          newbuf = iob_alloc(false);
          if (newbuf == NULL)
            {
              goto nospace;
            }

          next->io_flink = newbuf;
          next = newbuf;
          next->io_len = 0;

          if (next->io_len > left)
            {
              next->io_len = left;
            }

          noff = 0;
        }

      len = MIN(iob->io_len - moff, next->io_len - noff);

      src = (FAR uint8_t *) IOB_DATA(iob) + moff;
      dst = (FAR uint8_t *) IOB_DATA(next) + noff;

      for (i = 0; i < len; i++)
        {
          /* update MIC with clear text */
          b[j] ^= src[i];

          /* encrypt message */
          dst[i] = src[i] ^ s[j];
          if (++j < 16)
            continue;

          /* we have a full block, encrypt MIC */
          rijndael_encrypt(&ctx->rijndael, b, b);

          /* construct a new S_ctr block */
          ctr++;
          a[14] = ctr >> 8;
          a[15] = ctr & 0xff;
          rijndael_encrypt(&ctx->rijndael, a, s);
          j = 0;
        }

      moff += len;
      noff += len;
      left -= len;
    }
  if (j != 0)                   /* partial block, encrypt MIC */
    rijndael_encrypt(&ctx->rijndael, b, b);

  /* Reserve trailing space for MIC */

  if (IOB_FREESPACE(next) < IEEE80211_CCMP_MICLEN)
    {
      struct iob_s *newbuf;

      newbuf = iob_alloc(false);
      if (newbuf == NULL)
        {
          goto nospace;
        }

      next->io_flink = newbuf;
      next = newbuf;
      next->io_len = 0;
    }

  /* Finalize MIC, U := T XOR first-M-bytes( S_0 ) */

  mic = (FAR uint8_t *) IOB_DATA(next) + next->io_len;
  for (i = 0; i < IEEE80211_CCMP_MICLEN; i++)
    {
      mic[i] = b[i] ^ s0[i];
    }

  next->io_len += IEEE80211_CCMP_MICLEN;
  next0->io_pktlen += IEEE80211_CCMP_MICLEN;

  iob_free_chain(iob0);
  return next0;

nospace:
  iob_free_chain(iob0);
  if (next0 != NULL)
    {
      iob_free_chain(next0);
    }

  return NULL;
}
Пример #21
0
static void
rijndael128_encrypt(caddr_t key, u_int8_t *blk)
{
	rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
}
Пример #22
0
struct mbuf *
ieee80211_ccmp_encrypt(struct ieee80211com *ic, struct mbuf *m0,
    struct ieee80211_key *k)
{
	struct ieee80211_ccmp_ctx *ctx = k->k_priv;
	const struct ieee80211_frame *wh;
	const u_int8_t *src;
	u_int8_t *ivp, *mic, *dst;
	u_int8_t a[16], b[16], s0[16], s[16];
	struct mbuf *n0, *m, *n;
	int hdrlen, left, moff, noff, len;
	u_int16_t ctr;
	int i, j;

	MGET(n0, M_DONTWAIT, m0->m_type);
	if (n0 == NULL)
		goto nospace;
	if (m_dup_pkthdr(n0, m0, M_DONTWAIT))
		goto nospace;
	n0->m_pkthdr.len += IEEE80211_CCMP_HDRLEN;
	n0->m_len = MHLEN;
	if (n0->m_pkthdr.len >= MINCLSIZE - IEEE80211_CCMP_MICLEN) {
		MCLGET(n0, M_DONTWAIT);
		if (n0->m_flags & M_EXT)
			n0->m_len = n0->m_ext.ext_size;
	}
	if (n0->m_len > n0->m_pkthdr.len)
		n0->m_len = n0->m_pkthdr.len;

	/* copy 802.11 header */
	wh = mtod(m0, struct ieee80211_frame *);
	hdrlen = ieee80211_get_hdrlen(wh);
	memcpy(mtod(n0, caddr_t), wh, hdrlen);

	k->k_tsc++;	/* increment the 48-bit PN */

	/* construct CCMP header */
	ivp = mtod(n0, u_int8_t *) + hdrlen;
	ivp[0] = k->k_tsc;		/* PN0 */
	ivp[1] = k->k_tsc >> 8;		/* PN1 */
	ivp[2] = 0;			/* Rsvd */
	ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;	/* KeyID | ExtIV */
	ivp[4] = k->k_tsc >> 16;	/* PN2 */
	ivp[5] = k->k_tsc >> 24;	/* PN3 */
	ivp[6] = k->k_tsc >> 32;	/* PN4 */
	ivp[7] = k->k_tsc >> 40;	/* PN5 */

	/* construct initial B, A and S_0 blocks */
	ieee80211_ccmp_phase1(&ctx->rijndael, wh, k->k_tsc,
	    m0->m_pkthdr.len - hdrlen, b, a, s0);

	/* construct S_1 */
	ctr = 1;
	a[14] = ctr >> 8;
	a[15] = ctr & 0xff;
	rijndael_encrypt(&ctx->rijndael, a, s);

	/* encrypt frame body and compute MIC */
	j = 0;
	m = m0;
	n = n0;
	moff = hdrlen;
	noff = hdrlen + IEEE80211_CCMP_HDRLEN;
	left = m0->m_pkthdr.len - moff;
	while (left > 0) {
		if (moff == m->m_len) {
			/* nothing left to copy from m */
			m = m->m_next;
			moff = 0;
		}
		if (noff == n->m_len) {
			/* n is full and there's more data to copy */
			MGET(n->m_next, M_DONTWAIT, n->m_type);
			if (n->m_next == NULL)
				goto nospace;
			n = n->m_next;
			n->m_len = MLEN;
			if (left >= MINCLSIZE - IEEE80211_CCMP_MICLEN) {
				MCLGET(n, M_DONTWAIT);
				if (n->m_flags & M_EXT)
					n->m_len = n->m_ext.ext_size;
			}
			if (n->m_len > left)
				n->m_len = left;
			noff = 0;
		}
		len = min(m->m_len - moff, n->m_len - noff);

		src = mtod(m, u_int8_t *) + moff;
		dst = mtod(n, u_int8_t *) + noff;
		for (i = 0; i < len; i++) {
			/* update MIC with clear text */
			b[j] ^= src[i];
			/* encrypt message */
			dst[i] = src[i] ^ s[j];
			if (++j < 16)
				continue;
			/* we have a full block, encrypt MIC */
			rijndael_encrypt(&ctx->rijndael, b, b);
			/* construct a new S_ctr block */
			ctr++;
			a[14] = ctr >> 8;
			a[15] = ctr & 0xff;
			rijndael_encrypt(&ctx->rijndael, a, s);
			j = 0;
		}

		moff += len;
		noff += len;
		left -= len;
	}
	if (j != 0)	/* partial block, encrypt MIC */
		rijndael_encrypt(&ctx->rijndael, b, b);

	/* reserve trailing space for MIC */
	if (M_TRAILINGSPACE(n) < IEEE80211_CCMP_MICLEN) {
		MGET(n->m_next, M_DONTWAIT, n->m_type);
		if (n->m_next == NULL)
			goto nospace;
		n = n->m_next;
		n->m_len = 0;
	}
	/* finalize MIC, U := T XOR first-M-bytes( S_0 ) */
	mic = mtod(n, u_int8_t *) + n->m_len;
	for (i = 0; i < IEEE80211_CCMP_MICLEN; i++)
		mic[i] = b[i] ^ s0[i];
	n->m_len += IEEE80211_CCMP_MICLEN;
	n0->m_pkthdr.len += IEEE80211_CCMP_MICLEN;

	m_freem(m0);
	return n0;
 nospace:
	ic->ic_stats.is_tx_nombuf++;
	m_freem(m0);
	if (n0 != NULL)
		m_freem(n0);
	return NULL;
}
Пример #23
0
struct mbuf *
ieee80211_ccmp_decrypt(struct ieee80211com *ic, struct mbuf *m0,
    struct ieee80211_key *k)
{
	struct ieee80211_ccmp_ctx *ctx = k->k_priv;
	struct ieee80211_frame *wh;
	u_int64_t pn, *prsc;
	const u_int8_t *ivp, *src;
	u_int8_t *dst;
	u_int8_t mic0[IEEE80211_CCMP_MICLEN];
	u_int8_t a[16], b[16], s0[16], s[16];
	struct mbuf *n0, *m, *n;
	int hdrlen, left, moff, noff, len;
	u_int16_t ctr;
	int i, j;

	wh = mtod(m0, struct ieee80211_frame *);
	hdrlen = ieee80211_get_hdrlen(wh);
	ivp = (u_int8_t *)wh + hdrlen;

	if (m0->m_pkthdr.len < hdrlen + IEEE80211_CCMP_HDRLEN +
	    IEEE80211_CCMP_MICLEN) {
		m_freem(m0);
		return NULL;
	}
	/* check that ExtIV bit is set */
	if (!(ivp[3] & IEEE80211_WEP_EXTIV)) {
		m_freem(m0);
		return NULL;
	}

	/* retrieve last seen packet number for this frame type/priority */
	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
	    IEEE80211_FC0_TYPE_DATA) {
		u_int8_t tid = ieee80211_has_qos(wh) ?
		    ieee80211_get_qos(wh) & IEEE80211_QOS_TID : 0;
		prsc = &k->k_rsc[tid];
	} else	/* 11w: management frames have their own counters */
		prsc = &k->k_mgmt_rsc;

	/* extract the 48-bit PN from the CCMP header */
	pn = (u_int64_t)ivp[0]       |
	     (u_int64_t)ivp[1] <<  8 |
	     (u_int64_t)ivp[4] << 16 |
	     (u_int64_t)ivp[5] << 24 |
	     (u_int64_t)ivp[6] << 32 |
	     (u_int64_t)ivp[7] << 40;
	if (pn <= *prsc) {
		/* replayed frame, discard */
		ic->ic_stats.is_ccmp_replays++;
		m_freem(m0);
		return NULL;
	}

	MGET(n0, M_DONTWAIT, m0->m_type);
	if (n0 == NULL)
		goto nospace;
	if (m_dup_pkthdr(n0, m0, M_DONTWAIT))
		goto nospace;
	n0->m_pkthdr.len -= IEEE80211_CCMP_HDRLEN + IEEE80211_CCMP_MICLEN;
	n0->m_len = MHLEN;
	if (n0->m_pkthdr.len >= MINCLSIZE) {
		MCLGET(n0, M_DONTWAIT);
		if (n0->m_flags & M_EXT)
			n0->m_len = n0->m_ext.ext_size;
	}
	if (n0->m_len > n0->m_pkthdr.len)
		n0->m_len = n0->m_pkthdr.len;

	/* construct initial B, A and S_0 blocks */
	ieee80211_ccmp_phase1(&ctx->rijndael, wh, pn,
	    n0->m_pkthdr.len - hdrlen, b, a, s0);

	/* copy 802.11 header and clear protected bit */
	memcpy(mtod(n0, caddr_t), wh, hdrlen);
	wh = mtod(n0, struct ieee80211_frame *);
	wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;

	/* construct S_1 */
	ctr = 1;
	a[14] = ctr >> 8;
	a[15] = ctr & 0xff;
	rijndael_encrypt(&ctx->rijndael, a, s);

	/* decrypt frame body and compute MIC */
	j = 0;
	m = m0;
	n = n0;
	moff = hdrlen + IEEE80211_CCMP_HDRLEN;
	noff = hdrlen;
	left = n0->m_pkthdr.len - noff;
	while (left > 0) {
		if (moff == m->m_len) {
			/* nothing left to copy from m */
			m = m->m_next;
			moff = 0;
		}
		if (noff == n->m_len) {
			/* n is full and there's more data to copy */
			MGET(n->m_next, M_DONTWAIT, n->m_type);
			if (n->m_next == NULL)
				goto nospace;
			n = n->m_next;
			n->m_len = MLEN;
			if (left >= MINCLSIZE) {
				MCLGET(n, M_DONTWAIT);
				if (n->m_flags & M_EXT)
					n->m_len = n->m_ext.ext_size;
			}
			if (n->m_len > left)
				n->m_len = left;
			noff = 0;
		}
		len = min(m->m_len - moff, n->m_len - noff);

		src = mtod(m, u_int8_t *) + moff;
		dst = mtod(n, u_int8_t *) + noff;
		for (i = 0; i < len; i++) {
			/* decrypt message */
			dst[i] = src[i] ^ s[j];
			/* update MIC with clear text */
			b[j] ^= dst[i];
			if (++j < 16)
				continue;
			/* we have a full block, encrypt MIC */
			rijndael_encrypt(&ctx->rijndael, b, b);
			/* construct a new S_ctr block */
			ctr++;
			a[14] = ctr >> 8;
			a[15] = ctr & 0xff;
			rijndael_encrypt(&ctx->rijndael, a, s);
			j = 0;
		}

		moff += len;
		noff += len;
		left -= len;
	}
	if (j != 0)	/* partial block, encrypt MIC */
		rijndael_encrypt(&ctx->rijndael, b, b);

	/* finalize MIC, U := T XOR first-M-bytes( S_0 ) */
	for (i = 0; i < IEEE80211_CCMP_MICLEN; i++)
		b[i] ^= s0[i];

	/* check that it matches the MIC in received frame */
	m_copydata(m, moff, IEEE80211_CCMP_MICLEN, mic0);
	if (timingsafe_bcmp(mic0, b, IEEE80211_CCMP_MICLEN) != 0) {
		ic->ic_stats.is_ccmp_dec_errs++;
		m_freem(m0);
		m_freem(n0);
		return NULL;
	}

	/* update last seen packet number (MIC is validated) */
	*prsc = pn;

	m_freem(m0);
	return n0;
 nospace:
	ic->ic_stats.is_rx_nombuf++;
	m_freem(m0);
	if (n0 != NULL)
		m_freem(n0);
	return NULL;
}
Пример #24
0
/*-
 * Counter with CBC-MAC (CCM) - see RFC3610.
 * CCMP uses the following CCM parameters: M = 8, L = 2
 */
static void
ieee80211_ccmp_phase1(rijndael_ctx *ctx, const struct ieee80211_frame *wh,
    u_int64_t pn, int lm, u_int8_t b[16], u_int8_t a[16], u_int8_t s0[16])
{
	u_int8_t auth[32], nonce[13];
	u_int8_t *aad;
	u_int8_t tid = 0;
	int la, i;

	/* construct AAD (additional authenticated data) */
	aad = &auth[2];	/* skip l(a), will be filled later */
	*aad = wh->i_fc[0];
	/* 11w: conditionnally mask subtype field */
	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
	    IEEE80211_FC0_TYPE_DATA)
		*aad &= ~IEEE80211_FC0_SUBTYPE_MASK;
	aad++;
	/* protected bit is already set in wh */
	*aad = wh->i_fc[1];
	*aad &= ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
	    IEEE80211_FC1_MORE_DATA);
	/* 11n: conditionnally mask order bit */
	if (ieee80211_has_htc(wh))
		*aad &= ~IEEE80211_FC1_ORDER;
	aad++;
	IEEE80211_ADDR_COPY(aad, wh->i_addr1); aad += IEEE80211_ADDR_LEN;
	IEEE80211_ADDR_COPY(aad, wh->i_addr2); aad += IEEE80211_ADDR_LEN;
	IEEE80211_ADDR_COPY(aad, wh->i_addr3); aad += IEEE80211_ADDR_LEN;
	*aad++ = wh->i_seq[0] & ~0xf0;
	*aad++ = 0;
	if (ieee80211_has_addr4(wh)) {
		IEEE80211_ADDR_COPY(aad,
		    ((const struct ieee80211_frame_addr4 *)wh)->i_addr4);
		aad += IEEE80211_ADDR_LEN;
	}
	if (ieee80211_has_qos(wh)) {
		*aad++ = tid = ieee80211_get_qos(wh) & IEEE80211_QOS_TID;
		*aad++ = 0;
	}

	/* construct CCM nonce */
	nonce[ 0] = tid;
	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
	    IEEE80211_FC0_TYPE_MGT)
		nonce[0] |= 1 << 4;	/* 11w: set management bit */
	IEEE80211_ADDR_COPY(&nonce[1], wh->i_addr2);
	nonce[ 7] = pn >> 40;	/* PN5 */
	nonce[ 8] = pn >> 32;	/* PN4 */
	nonce[ 9] = pn >> 24;	/* PN3 */
	nonce[10] = pn >> 16;	/* PN2 */
	nonce[11] = pn >> 8;	/* PN1 */
	nonce[12] = pn;		/* PN0 */

	/* add 2 authentication blocks (including l(a) and padded AAD) */
	la = aad - &auth[2];		/* fill l(a) */
	auth[0] = la >> 8;
	auth[1] = la & 0xff;
	memset(aad, 0, 30 - la);	/* pad AAD with zeros */

	/* construct first block B_0 */
	b[ 0] = 89;	/* Flags = 64*Adata + 8*((M-2)/2) + (L-1) */
	memcpy(&b[1], nonce, 13);
	b[14] = lm >> 8;
	b[15] = lm & 0xff;
	rijndael_encrypt(ctx, b, b);

	for (i = 0; i < 16; i++)
		b[i] ^= auth[i];
	rijndael_encrypt(ctx, b, b);
	for (i = 0; i < 16; i++)
		b[i] ^= auth[16 + i];
	rijndael_encrypt(ctx, b, b);

	/* construct S_0 */
	a[ 0] = 1;	/* Flags = L' = (L-1) */
	memcpy(&a[1], nonce, 13);
	a[14] = a[15] = 0;
	rijndael_encrypt(ctx, a, s0);
}
Пример #25
0
long int
dtls_ccm_encrypt_message(rijndael_ctx *ctx, size_t M, size_t L, 
			 unsigned char N[DTLS_CCM_BLOCKSIZE], 
			 unsigned char *msg, size_t lm, 
			 const unsigned char *aad, size_t la) {
  size_t i, len;
  unsigned long C;
  unsigned long counter = 1; /* \bug does not work correctly on ia32 when
			             lm >= 2^16 */
  unsigned char A[DTLS_CCM_BLOCKSIZE]; /* A_i blocks for encryption input */
  unsigned char B[DTLS_CCM_BLOCKSIZE]; /* B_i blocks for CBC-MAC input */
  unsigned char S[DTLS_CCM_BLOCKSIZE]; /* S_i = encrypted A_i blocks */
  unsigned char X[DTLS_CCM_BLOCKSIZE]; /* X_i = encrypted B_i blocks */

  len = lm;			/* save original length */
  /* create the initial authentication block B0 */
  block0(M, L, la, lm, N, B);
  add_auth_data(ctx, aad, la, B, X);

  /* initialize block template */
  A[0] = L-1;

  /* copy the nonce */
  memcpy(A + 1, N, DTLS_CCM_BLOCKSIZE - L);
  
  while (lm >= DTLS_CCM_BLOCKSIZE) {
    /* calculate MAC */
    mac(ctx, msg, DTLS_CCM_BLOCKSIZE, B, X);

    /* encrypt */
    encrypt(ctx, L, counter, msg, DTLS_CCM_BLOCKSIZE, A, S);

    /* update local pointers */
    lm -= DTLS_CCM_BLOCKSIZE;
    msg += DTLS_CCM_BLOCKSIZE;
    counter++;
  }

  if (lm) {
    /* Calculate MAC. The remainder of B must be padded with zeroes, so
     * B is constructed to contain X ^ msg for the first lm bytes (done in
     * mac() and X ^ 0 for the remaining DTLS_CCM_BLOCKSIZE - lm bytes
     * (i.e., we can use memcpy() here).
     */
    memcpy(B + lm, X + lm, DTLS_CCM_BLOCKSIZE - lm);
    mac(ctx, msg, lm, B, X);

    /* encrypt */
    encrypt(ctx, L, counter, msg, lm, A, S);

    /* update local pointers */
    msg += lm;
  }
  
  /* calculate S_0 */  
  SET_COUNTER(A, L, 0, C);
  rijndael_encrypt(ctx, A, S);

  for (i = 0; i < M; ++i)
    *msg++ = X[i] ^ S[i];

  return len + M;
}
Пример #26
0
static void ccmp_init_blocks(
	rijndael_ctx *ctx,
        PAIRPDCAP_MAC_FRAME wh,
	UINT64 pn,
	size_t dlen,
	UINT8 b0[AES_BLOCK_LEN],
	UINT8 aad[2 * AES_BLOCK_LEN],
	UINT8 a[AES_BLOCK_LEN],
	UINT8 b[AES_BLOCK_LEN])
{
#define IS_4ADDRESS(wh) \
	((wh->fc[1] & AIRPDCAP_FC1_DIR_MASK) == AIRPDCAP_FC1_DIR_DSTODS)
#define IS_QOS_DATA(wh) AIRPDCAP_QOS_HAS_SEQ(wh)

	memset(aad, 0, 2*AES_BLOCK_LEN);

	/* CCM Initial Block:
	* Flag (Include authentication header, M=3 (8-octet MIC),
	*       L=1 (2-octet Dlen))
	* Nonce: 0x00 | A2 | PN
	* Dlen */
	b0[0] = 0x59;
	/* NB: b0[1] set below */
	AIRPDCAP_ADDR_COPY(b0 + 2, wh->addr2);
	b0[8] = (UINT8)(pn >> 40);
	b0[9] = (UINT8)(pn >> 32);
	b0[10] = (UINT8)(pn >> 24);
	b0[11] = (UINT8)(pn >> 16);
	b0[12] = (UINT8)(pn >> 8);
	b0[13] = (UINT8)(pn >> 0);
	b0[14] = (UINT8)((UINT8)(dlen >> 8) & 0xff);
	b0[15] = (UINT8)(dlen & 0xff);

	/* AAD:
	* FC with bits 4..6 and 11..13 masked to zero; 14 is always one
	* A1 | A2 | A3
	* SC with bits 4..15 (seq#) masked to zero
	* A4 (if present)
	* QC (if present)
	*/
	aad[0] = 0;     /* AAD length >> 8 */
	/* NB: aad[1] set below */
	aad[2] = (UINT8)(wh->fc[0] & 0x8f);    /* XXX magic #s */
	aad[3] = (UINT8)(wh->fc[1] & 0xc7);    /* XXX magic #s */
	/* NB: we know 3 addresses are contiguous */
	memcpy(aad + 4, &wh->addr1[0], 3 * AIRPDCAP_MAC_LEN);
	aad[22] = (UINT8)(wh->seq[0] & AIRPDCAP_SEQ_FRAG_MASK);
	aad[23] = 0; /* all bits masked */
	/*
	* Construct variable-length portion of AAD based
	* on whether this is a 4-address frame/QOS frame.
	* We always zero-pad to 32 bytes before running it
	* through the cipher.
	*
	* We also fill in the priority bits of the CCM
	* initial block as we know whether or not we have
	* a QOS frame.
	*/
	if (IS_4ADDRESS(wh)) {
		AIRPDCAP_ADDR_COPY(aad + 24,
			((PAIRPDCAP_MAC_FRAME_ADDR4)wh)->addr4);
		if (IS_QOS_DATA(wh)) {
			PAIRPDCAP_MAC_FRAME_ADDR4_QOS qwh4 =
				(PAIRPDCAP_MAC_FRAME_ADDR4_QOS) wh;
			aad[30] = (UINT8)(qwh4->qos[0] & 0x0f);/* just priority bits */
			aad[31] = 0;
			b0[1] = aad[30];
			aad[1] = 22 + AIRPDCAP_MAC_LEN + 2;
		} else {
			memset(&aad[30], 0, 2);
			b0[1] = 0;
			aad[1] = 22 + AIRPDCAP_MAC_LEN;
		}
	} else {
		if (IS_QOS_DATA(wh)) {
			PAIRPDCAP_MAC_FRAME_QOS qwh =
				(PAIRPDCAP_MAC_FRAME_QOS) wh;
			aad[24] = (UINT8)(qwh->qos[0] & 0x0f); /* just priority bits */
			aad[25] = 0;
			b0[1] = aad[24];
			aad[1] = 22 + 2;
		} else {
			memset(&aad[24], 0, 2);
			b0[1] = 0;
			aad[1] = 22;
		}
		memset(&aad[26], 0, 4);
	}

	/* Start with the first block and AAD */
	rijndael_encrypt(ctx, b0, a);
	XOR_BLOCK(a, aad, AES_BLOCK_LEN);
	rijndael_encrypt(ctx, a, a);
	XOR_BLOCK(a, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
	rijndael_encrypt(ctx, a, a);
	b0[0] &= 0x07;
	b0[14] = b0[15] = 0;
	rijndael_encrypt(ctx, b0, b);

	/** //XOR( m + len - 8, b, 8 ); **/
#undef  IS_QOS_DATA
#undef  IS_4ADDRESS
}
Пример #27
0
/** 
 * Creates the CBC-MAC for the additional authentication data that
 * is sent in cleartext. 
 *
 * \param ctx  The crypto context for the AES encryption.
 * \param msg  The message starting with the additional authentication data.
 * \param la   The number of additional authentication bytes in \p msg.
 * \param B    The input buffer for crypto operations. When this function
 *             is called, \p B must be initialized with \c B0 (the first
 *             authentication block.
 * \param X    The output buffer where the result of the CBC calculation
 *             is placed.
 * \return     The result is written to \p X.
 */
void
add_auth_data(rijndael_ctx *ctx, const unsigned char *msg, size_t la,
	      unsigned char B[DTLS_CCM_BLOCKSIZE], 
	      unsigned char X[DTLS_CCM_BLOCKSIZE]) {
  size_t i,j; 

  rijndael_encrypt(ctx, B, X);

  memset(B, 0, DTLS_CCM_BLOCKSIZE);

  if (!la)
    return;

#ifndef WITH_CONTIKI
    if (la < 0xFF00) {		/* 2^16 - 2^8 */
      j = 2;
      dtls_int_to_uint16(B, la);
  } else if (la <= UINT32_MAX) {
      j = 6;
      dtls_int_to_uint16(B, 0xFFFE);
      dtls_int_to_uint32(B+2, la);
    } else {
      j = 10;
      dtls_int_to_uint16(B, 0xFFFF);
      dtls_ulong_to_uint64(B+2, la);
    }
#else /* WITH_CONTIKI */
  /* With Contiki, we are building for small devices and thus
   * anticipate that the number of additional authentication bytes
   * will not exceed 65280 bytes (0xFF00) and we can skip the
   * workarounds required for j=6 and j=10 on devices with a word size
   * of 32 bits or 64 bits, respectively.
   */

  assert(la < 0xFF00);
  j = 2;
  dtls_int_to_uint16(B, la);
#endif /* WITH_CONTIKI */

    i = min(DTLS_CCM_BLOCKSIZE - j, la);
    memcpy(B + j, msg, i);
    la -= i;
    msg += i;
    
    memxor(B, X, DTLS_CCM_BLOCKSIZE);
  
  rijndael_encrypt(ctx, B, X);
  
  while (la > DTLS_CCM_BLOCKSIZE) {
    for (i = 0; i < DTLS_CCM_BLOCKSIZE; ++i)
      B[i] = X[i] ^ *msg++;
    la -= DTLS_CCM_BLOCKSIZE;

    rijndael_encrypt(ctx, B, X);
  }
  
  if (la) {
    memset(B, 0, DTLS_CCM_BLOCKSIZE);
    memcpy(B, msg, la);
    memxor(B, X, DTLS_CCM_BLOCKSIZE);

    rijndael_encrypt(ctx, B, X);  
  } 
}
Пример #28
0
static void ciph_encrypt(ciphCtx *ctx, const uint8_t *in, uint8_t *out)
{
	rijndael_encrypt(ctx, (const uint32_t *)in, (uint32_t *)out);
}
Пример #29
0
static void
ciph_encrypt(CIPH_CTX * ctx, const uint8 *in, uint8 *out)
{
	rijndael_encrypt(ctx, (const uint32 *) in, (uint32 *) out);
}
Пример #30
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(aestest, ev, data)
{
    static int i, j;
    unsigned long start, end;
    static struct etimer periodic_timer;

    PROCESS_BEGIN();

    printf("#Random AES-128 implementation test for %s.\n", TARGET_NAME);
    printf("#Using OpenBSD optimised AES implementation.\n");
    printf("#Rounds in each sample: %d\n", NROUND);
    printf("#Sample size: %d\n", NSAMPLE);
    printf("#Rtimer clock ticks per second on this platform is : %lu\n",
           (unsigned long) RTIMER_SECOND);
    printf("#plaintext addr: %ul\n", (unsigned int)plaintext);
    printf("#ciphertext addr: %ul\n", (unsigned int)ciphertext);

    etimer_set(&periodic_timer, (1 * CLOCK_SECOND));

    //Initialise plaintext.
    for (j = 0; j < NROUND; j++) {
        memcpy(plaintext[j], fixed_data, AES_BLOCK_LEN);
    }

    //Begin test.
    for (i = 0; i < NSAMPLE; i++) {
        PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
        etimer_reset(&periodic_timer);

#ifdef VERBOSE_AESTEST
        printf("#Sample %d/%d\n", i + 1, NSAMPLE);
        PrintBlock("#Key\t:", Aes128Key, "\n");
        PrintBlock("#Plaintext\t: ", plaintext[0], "\n");
#endif
        //Set key.
        rijndael_set_key_enc_only(&aes_ctx, Aes128Key, 8 * AES_KEY_LEN);
        rijndael_encrypt(&aes_ctx, dummyplaintext, dummyciphertext);

        //Timing AES.
        start = RTIMER_NOW();
#ifdef CALIBRATE_FRAMEWORK
	for (j = 0; j < NROUND * 10; j++){
	    random_rand();
	}
#else
        for (j = 0; j < NROUND; j++) {
            rijndael_encrypt(&aes_ctx, plaintext[j], ciphertext[j]);
        }
#endif
        end = RTIMER_NOW();

#ifdef VERBOSE_AESTEST
        //Print result.
        PrintBlock("#Ciphertext\t: ", ciphertext[0], "\n");
        printf("#Round\t: %d\n", NROUND);
        printf("#Start\t: %lu\n", start);
        printf("#End\t: %lu\n", end);
        printf("#Time Elapsed\t:\n");
#endif
	//Print execution time.
        printf("%lu\n", end - start);
	
	finalise();
    }

    printf("#%d tests done for %s.\n", NSAMPLE, TARGET_NAME);

    PROCESS_END();
}