예제 #1
0
파일: 2fish.c 프로젝트: pktmonky/SLAE
/* the key schedule routine */
void keySched(BYTE M[], int N, u32 **S, u32 K[40], int *k)
{
    u32 Mo[4], Me[4];
    int i, j;
    BYTE vector[8];
    u32 A, B;

    *k = (N + 63) / 64;
    *S = (u32*)malloc(sizeof(u32) * (*k));

    for (i = 0; i < *k; i++)
    {
	Me[i] = BSWAP(((u32*)M)[2*i]);
	Mo[i] = BSWAP(((u32*)M)[2*i+1]);
    }

    for (i = 0; i < *k; i++)
    {
	for (j = 0; j < 4; j++) vector[j] = _b(Me[i], j);
	for (j = 0; j < 4; j++) vector[j+4] = _b(Mo[i], j);
	(*S)[(*k)-i-1] = RSMatrixMultiply(vector);
    }
    for (i = 0; i < 20; i++)
    {
	A = h(2*i*RHO, Me, *k);
	B = ROL(h(2*i*RHO + RHO, Mo, *k), 8);
	K[2*i] = A+B;
	K[2*i+1] = ROL(A + 2*B, 9);
    }
}	
예제 #2
0
파일: rc5.c 프로젝트: TheTypoMaster/AH4222
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
    unsigned long L[64], S[50], A, B, i, j, v, s, t, l;

    _ARGCHK(skey != NULL);
    _ARGCHK(key != NULL);

    /* test parameters */
    if (num_rounds == 0) { 
       num_rounds = rc5_desc.default_rounds;
    }

    if (num_rounds < 12 || num_rounds > 24) { 
       return CRYPT_INVALID_ROUNDS;
    }

    /* key must be between 64 and 1024 bits */
    if (keylen < 8 || keylen > 128) {
       return CRYPT_INVALID_KEYSIZE;
    }

    /* copy the key into the L array */
    for (A = i = j = 0; i < (unsigned long)keylen; ) { 
        A = (A << 8) | ((unsigned long)(key[i++] & 255));
        if ((i & 3) == 0) {
           L[j++] = BSWAP(A);
           A = 0;
        }
    }

    if ((keylen & 3) != 0) { 
       A <<= (unsigned long)((8 * (4 - (keylen&3)))); 
       L[j++] = BSWAP(A);
    }

    /* setup the S array */
    t = (unsigned long)(2 * (num_rounds + 1));
    S[0] = 0xB7E15163UL;
    for (i = 1; i < t; i++) S[i] = S[i - 1] + 0x9E3779B9UL;

    /* mix buffer */
    s = 3 * MAX(t, j);
    l = j;
    for (A = B = i = j = v = 0; v < s; v++) { 
        A = S[i] = ROL(S[i] + A + B, 3);
        B = L[j] = ROL(L[j] + A + B, (A+B));
        i = (i + 1) % t;
        j = (j + 1) % l;
    }
    
    /* copy to key */
    for (i = 0; i < t; i++) {
        skey->rc5.K[i] = S[i];
    }
    skey->rc5.rounds = num_rounds;
    return CRYPT_OK;
}
예제 #3
0
파일: rc6.c 프로젝트: TheTypoMaster/AH4222
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
    unsigned long L[64], S[50], A, B, i, j, v, s, t, l;

    _ARGCHK(key != NULL);
    _ARGCHK(skey != NULL);

    /* test parameters */
    if (num_rounds != 0 && num_rounds != 20) { 
       return CRYPT_INVALID_ROUNDS;
    }

    /* key must be between 64 and 1024 bits */
    if (keylen < 8 || keylen > 128) {
       return CRYPT_INVALID_KEYSIZE;
    }

    /* copy the key into the L array */
    for (A = i = j = 0; i < (unsigned long)keylen; ) { 
        A = (A << 8) | ((unsigned long)(key[i++] & 255));
        if (!(i & 3)) {
           L[j++] = BSWAP(A);
           A = 0;
        }
    }

    /* handle odd sized keys */
    if (keylen & 3) { 
       A <<= (8 * (4 - (keylen&3))); 
       L[j++] = BSWAP(A); 
    }

    /* setup the S array */
    t = 44;                                     /* fixed at 20 rounds */
    S[0] = 0xB7E15163UL;
    for (i = 1; i < t; i++) 
        S[i] = S[i - 1] + 0x9E3779B9UL;

    /* mix buffer */
    s = 3 * MAX(t, j);
    l = j;
    for (A = B = i = j = v = 0; v < s; v++) { 
        A = S[i] = ROL(S[i] + A + B, 3);
        B = L[j] = ROL(L[j] + A + B, (A+B));
        i = (i + 1) % t;
        j = (j + 1) % l;
    }
    
    /* copy to key */
    for (i = 0; i < t; i++) { 
        skey->rc6.K[i] = S[i];
    }
    return CRYPT_OK;
}
void HashSHA1Final(SHA1_Context* ctx, void* hash)
{
	if (ctx->remain_len >= HASH_BLOCK_SHA1 - 8)
	{
		ctx->remain[ctx->remain_len] = 0x80;
		ctx->remain_len++;
		memset(ctx->remain + ctx->remain_len, 0, HASH_BLOCK_SHA1 - ctx->remain_len);
		HashSHA1Block(ctx->remain,ctx);
		memset(ctx->remain, 0, HASH_BLOCK_SHA1 - 8);
		ctx->len <<= 3;
		*(unsigned int*)(ctx->remain + HASH_BLOCK_SHA1 - 8) = BSWAP(ctx->len_high);
		*(unsigned int*)(ctx->remain + HASH_BLOCK_SHA1 - 4) = BSWAP(ctx->len_low);
		HashSHA1Block(ctx->remain,ctx);
	}
	else
	{
		ctx->remain[ctx->remain_len] = 0x80;
		ctx->remain_len++;
		memset(ctx->remain + ctx->remain_len, 0, HASH_BLOCK_SHA1 - 8 - ctx->remain_len);
		ctx->len <<= 3;
		*(unsigned int*)(ctx->remain + HASH_BLOCK_SHA1 - 8) = BSWAP(ctx->len_high);
		*(unsigned int*)(ctx->remain + HASH_BLOCK_SHA1 - 4) = BSWAP(ctx->len_low);
		HashSHA1Block(ctx->remain,ctx);
	}
	unsigned long* h = (unsigned long*)hash;
	h[0] = BSWAP(ctx->h0);
	h[1] = BSWAP(ctx->h1);
	h[2] = BSWAP(ctx->h2);
	h[3] = BSWAP(ctx->h3);
	h[4] = BSWAP(ctx->h4);
	unsigned char* hs = (unsigned char*)hash;

}
예제 #5
0
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
    ulong32 L[64], *S, A, B, i, j, v, s, t, l;

    LTC_ARGCHK(skey != NULL);
    LTC_ARGCHK(key  != NULL);
    
    /* test parameters */
    if (num_rounds == 0) { 
       num_rounds = rc5_desc.default_rounds;
    }

    if (num_rounds < 12 || num_rounds > 24) { 
       return CRYPT_INVALID_ROUNDS;
    }

    /* key must be between 64 and 1024 bits */
    if (keylen < 8 || keylen > 128) {
       return CRYPT_INVALID_KEYSIZE;
    }
    
    skey->rc5.rounds = num_rounds;
    S = skey->rc5.K;

    /* copy the key into the L array */
    for (A = i = j = 0; i < (ulong32)keylen; ) { 
        A = (A << 8) | ((ulong32)(key[i++] & 255));
        if ((i & 3) == 0) {
           L[j++] = BSWAP(A);
           A = 0;
        }
    }

    if ((keylen & 3) != 0) { 
       A <<= (ulong32)((8 * (4 - (keylen&3)))); 
       L[j++] = BSWAP(A);
    }

    /* setup the S array */
    t = (ulong32)(2 * (num_rounds + 1));
    XMEMCPY(S, stab, t * sizeof(*S));

    /* mix buffer */
    s = 3 * MAX(t, j);
    l = j;
    for (A = B = i = j = v = 0; v < s; v++) { 
        A = S[i] = ROLc(S[i] + A + B, 3);
        B = L[j] = ROL(L[j] + A + B, (A+B));
        if (++i == t) { i = 0; }
        if (++j == l) { j = 0; }
    }
    return CRYPT_OK;
}
예제 #6
0
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
    ulong32 L[64], S[50], A, B, i, j, v, s, l;

    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(skey != NULL);

    /* test parameters */
    if (num_rounds != 0 && num_rounds != 20) { 
       return CRYPT_INVALID_ROUNDS;
    }

    /* key must be between 64 and 1024 bits */
    if (keylen < 8 || keylen > 128) {
       return CRYPT_INVALID_KEYSIZE;
    }

    /* copy the key into the L array */
    for (A = i = j = 0; i < (ulong32)keylen; ) { 
        A = (A << 8) | ((ulong32)(key[i++] & 255));
        if (!(i & 3)) {
           L[j++] = BSWAP(A);
           A = 0;
        }
    }

    /* handle odd sized keys */
    if (keylen & 3) { 
       A <<= (8 * (4 - (keylen&3))); 
       L[j++] = BSWAP(A); 
    }

    /* setup the S array */
    XMEMCPY(S, stab, 44 * sizeof(stab[0]));

    /* mix buffer */
    s = 3 * MAX(44, j);
    l = j;
    for (A = B = i = j = v = 0; v < s; v++) { 
        A = S[i] = ROLc(S[i] + A + B, 3);
        B = L[j] = ROL(L[j] + A + B, (A+B));
        if (++i == 44) { i = 0; }
        if (++j == l)  { j = 0; }
    }
    
    /* copy to key */
    for (i = 0; i < 44; i++) { 
        skey->rc6.K[i] = S[i];
    }
    return CRYPT_OK;
}
예제 #7
0
파일: biniku.c 프로젝트: amayra/arc_conv
static int biniku_asm_local(FILE *fi, uint **m) {
	uint a, n, i = 0, p = 0;

	READ(&n, 4);
	printf("dd %i", n);
	for(i = 0; i < n; i++) {
	  READ(&a, 4);
	  if(i & 3) printf(", _x%04X", a);
	  else printf("\nm2 _x%04X", a);
	}
	printf("\n_x:\n");

	a = ftell(fi);
	biniku_jmp(fi, &i, 0);
	if(!(*m = malloc((i + n) << 2))) return -1;
	**m = i; if(i > 1) {
	  if(fseek(fi, a, SEEK_SET)) return -1;
	  biniku_jmp(fi, *m, i);
	}
	if(n) {
	  if(fseek(fi, 4, SEEK_SET)) return -1;
	  i = **m; **m = i + n;
	  READ(*m + i, n << 2);
	}
	if(fseek(fi, a, SEEK_SET)) return -1;

	for(;;) {
	  for(n = **m, i = 1; i < n; i++) if((*m)[i] == p) { printf("_x%04X:\n", p); break; }
	  LODSB; p++;
	  printf("m1 0x%02X", a);
	  switch(biniku_code(a)) {

	  case 1:	  // offset
	    READ(&a, 4); p += 4;
	    printf(", _x%04X", BSWAP(a));
	    break;

	  case 2:	  // int
	    READ(&a, 4); p += 4;
	    printf(", 0x%08X", BSWAP(a));
	    break;

	  case 3:	  // string
	    printf(", {");
	    if(biniku_asmstr(fi, &p)) return -1;
	    putchar('}');
	    break;
	  }
	  putchar('\n');
	}
	return 0;
}
예제 #8
0
파일: 2fish.c 프로젝트: pktmonky/SLAE
inline void decrypt(u32 K[40], u32 S[4][256], BYTE PT[16])
{
    u32 T0, T1;
    u32 R0, R1, R2, R3;

    /* load/byteswap/whiten input */
    R3 = K[7] ^ BSWAP(((u32*)PT)[3]);
    R2 = K[6] ^ BSWAP(((u32*)PT)[2]);
    R1 = K[5] ^ BSWAP(((u32*)PT)[1]);
    R0 = K[4] ^ BSWAP(((u32*)PT)[0]);

    DEC_ROUND(R0, R1, R2, R3, 15);
    DEC_ROUND(R2, R3, R0, R1, 14);
    DEC_ROUND(R0, R1, R2, R3, 13);
    DEC_ROUND(R2, R3, R0, R1, 12);
    DEC_ROUND(R0, R1, R2, R3, 11);
    DEC_ROUND(R2, R3, R0, R1, 10);
    DEC_ROUND(R0, R1, R2, R3, 9);
    DEC_ROUND(R2, R3, R0, R1, 8);
    DEC_ROUND(R0, R1, R2, R3, 7);
    DEC_ROUND(R2, R3, R0, R1, 6);
    DEC_ROUND(R0, R1, R2, R3, 5);
    DEC_ROUND(R2, R3, R0, R1, 4);
    DEC_ROUND(R0, R1, R2, R3, 3);
    DEC_ROUND(R2, R3, R0, R1, 2);
    DEC_ROUND(R0, R1, R2, R3, 1);
    DEC_ROUND(R2, R3, R0, R1, 0);

    /* load/byteswap/whiten output */
    ((u32*)PT)[3] = BSWAP(R1 ^ K[3]);
    ((u32*)PT)[2] = BSWAP(R0 ^ K[2]);
    ((u32*)PT)[1] = BSWAP(R3 ^ K[1]);
    ((u32*)PT)[0] = BSWAP(R2 ^ K[0]);

}
void HashSHA256Block(void* hash_block, SHA256_Context* ctx)
{
	unsigned int a,b,c,d,e,f,g,h,T1,T2,i;
	unsigned int w[0x40];
	unsigned char* block = (unsigned char*)hash_block;
	a = ctx->h0; b = ctx->h1;
	c = ctx->h2; d = ctx->h3;
	e = ctx->h4; f = ctx->h5;
	g = ctx->h6; h = ctx->h7;
	for (i = 0; i < 16; i++) w[i] = BSWAP(*(unsigned int*)(block + i * 4));
	for (i = 16; i < 64; i++) w[i] = SigmaS1(w[i-2]) + w[i-7] + SigmaS0(w[i-15]) + w[i-16];
	for (i = 0; i < 64; i++)
	{
		T1 = h + SigmaB1(e) + Ch(e,f,g) + sha256_constant[i] + w[i];
		T2 = SigmaB0(a) + Maj(a,b,c);
		h = g;
		g = f;
		f = e;
		e = d + T1;
		d = c;
		c = b;
		b = a;
		a = T1 + T2;
	}
	ctx->h0 += a;
	ctx->h1 += b;
	ctx->h2 += c;
	ctx->h3 += d;
	ctx->h4 += e;
	ctx->h5 += f;
	ctx->h6 += g;
	ctx->h7 += h;
	a = b = c = d = e = f = g = h = T1 = T2 = 0;
	memset(w,0,0x100);
}
예제 #10
0
/* rewind to beginning */
void faad_rewindbits(bitfile *ld)
{
    uint32_t tmp;

    tmp = ld->start[0];
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufa = tmp;

    tmp = ld->start[1];
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufb = tmp;
    ld->bits_left = 32;
    ld->tail = &ld->start[2];
    ld->bytes_used = 0;
    ld->no_more_reading = 0;
}
예제 #11
0
파일: biniku.c 프로젝트: amayra/arc_conv
static int biniku_fix(FILE *fi, FILE *fo, void *m) {
	uint a, i, n, p = 0, x;

	if(fseek(fi, 0, SEEK_SET)) return -1;
	if(fseek(fo, 4, SEEK_SET)) return -1;
	READ(&n, 4);
	for(i = 0; i < n; i++) {
	  READ(&a, 4); a = reloc_fix(m, a);
	  fwrite(&a, 1, 4, fo);
	}
	n = n * 4 + 4;

	for(;;) {
	  LODSB; p++;
	  switch(biniku_code(a)) {

	  case 1:	  // offset
	    READ(&a, 4);
	    a = BSWAP(a);
	    if((x = reloc_fix(m, a)) != a) {
	      a = BSWAP(x); x = n + reloc_fix(m, p);
	      // printf("change %08X %08X\n", x, a);
	      if(fseek(fo, x, SEEK_SET)) return -1;
	      fwrite(&a, 1, 4, fo);
	    }
	    p += 4;
	    break;
	  case 2:	  // int
	    READ(&a, 4); p += 4;
	    break;
	  case 3:	  // string
	    if(a != 0x0A) break;
	    for(;;) {
	      LODSB; p++;
	      if(!a) break;
	    }
	    break;
	  }
	}
	return 0;
}
예제 #12
0
void ei_insw(u32 addr, void *vbuf, int len)
{
	volatile u16 *rp;
	u16 w, *buf;

	buf = (u16 *) vbuf;
	rp = (volatile u16 *) NE_DATA_PTR(addr);
	for (; (len > 0); len--) {
		w = *rp;
		*buf++ = BSWAP(w);
	}
}
예제 #13
0
/* reset bitstream state */
void
BitstreamReset(Bitstream * const bs)
{
    uint32  tmp;

    bs->tail = bs->start;

    tmp = *bs->start;
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    bs->bufa = tmp;

    tmp = *(bs->start + 1);
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    bs->bufb = tmp;

    bs->buf = 0;
    bs->pos = 0;
}
예제 #14
0
ComponentResult FFAvi_MovieImportValidateDataRef(ff_global_ptr storage, Handle dataRef, OSType dataRefType, UInt8 *valid)
{
	ComponentResult result = noErr;
	DataHandler dataHandler = NULL;
	uint8_t buf[PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE] = {0};
	AVProbeData pd;
	ByteIOContext *byteContext;

	/* default */
	*valid = 0;
	
	/* Get a data handle and read a probe of data */
	result = OpenADataHandler(dataRef, dataRefType, NULL, 0, NULL, kDataHCanRead, &dataHandler);
	if(result || !dataHandler) goto bail;
	
	pd.buf = buf;
	pd.buf_size = PROBE_BUF_SIZE;
	
	result = DataHScheduleData(dataHandler, (Ptr)pd.buf, 0, PROBE_BUF_SIZE, 0, NULL, NULL);
	require_noerr(result,bail);
	
	FFInitFFmpeg();
	storage->format = av_probe_input_format(&pd, 1);
	if(storage->format != NULL) {
		*valid = 255; /* This means we can read the data */
		
		/* we don't do MJPEG's Huffman tables right yet, and DV video seems to have 
		an aspect ratio coded in the bitstream that ffmpeg doesn't read, so let Apple's 
		AVI importer handle AVIs with these two video types */
		if (IS_AVI(storage->componentType)) {
			/* Prepare the iocontext structure */
			result = url_open_dataref(&byteContext, dataRef, dataRefType, NULL, NULL, NULL);
			require_noerr(result, bail);
			
			OSType fourcc = get_avi_strf_fourcc(byteContext);
			enum CodecID id = ff_codec_get_id(ff_codec_bmp_tags, BSWAP(fourcc));
			
			if (id == CODEC_ID_MJPEG || id == CODEC_ID_DVVIDEO || id == CODEC_ID_RAWVIDEO || id == CODEC_ID_MSVIDEO1 || id == CODEC_ID_MSRLE)
				*valid = 0;
			
			url_fclose(byteContext);
		}
	}
		
bail:
		if(dataHandler)
			CloseComponent(dataHandler);
	
	return result;
} /* FFAvi_MovieImportValidateDataRef() */
예제 #15
0
/* initialise bitstream structure */
void
BitstreamInit(Bitstream *const bs, void *const bitstream, uint32 length)
{
    uint32  tmp;

    bs->start = bs->tail = (uint32 *) bitstream;
    tmp = *(uint32 *) bitstream;

#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    bs->bufa = tmp;
    tmp = *((uint32 *) bitstream + 1);

#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    bs->bufb = tmp;

    bs->buf = 0;
    bs->pos = 0;
    bs->length = length;
}
예제 #16
0
파일: rc6.c 프로젝트: 0x00dec0de/GMbot
void __stdcall RC6KeySetup (
	HRC6 hAlgorithm, 
	unsigned char * key
	)
{
  unsigned long L[64], S[50], A, B, i, j, v, s, t, l;

  /* copy the key into the L array */
  for (A = i = j = 0; i < RC6_KEY_CHARS;)
  {
      A = (A << 8) | ((unsigned long) (key[i++] & 255));
      if (!(i & 3))
	  {
		  L[j++] = BSWAP (A);
		  A = 0;
	  }
  }

  /* setup the S array */
  t = ROUNDKEYS;			/* fixed at 20 rounds */
  S[0] = 0xB7E15163UL;
  for (i = 1; i < t; i++)
    S[i] = S[i - 1] + 0x9E3779B9UL;

  /* mix buffer */
  s = 3 * MAX (t, j);
  l = j;
  for (A = B = i = j = v = 0; v < s; v++)
    {
      A = S[i] = ROL (S[i] + A + B, 3);
      B = L[j] = ROL (L[j] + A + B, (A + B));
      i = (i + 1) % t;
      j = (j + 1) % l;
    }

  /* copy to key */
  for (i = 0; i < t; i++)
    {
      hAlgorithm->skey[i] = S[i];
    }

#ifdef _RC6_MODE_CBC
	hAlgorithm->vector[0] = 0;
	hAlgorithm->vector[1] = 0;
	hAlgorithm->vector[2] = 0;
	hAlgorithm->vector[3] = 0;
#endif

}
예제 #17
0
/* move bitstream position forward by "bits" bits */
void
BitstreamForward(Bitstream * const bs, const uint32 bits)
{
    bs->pos += bits;

    if (bs->pos >= 32)
    {
        uint32  b = bs->buf;
#ifndef ARCH_IS_BIG_ENDIAN
        BSWAP(b);
#endif
        *bs->tail++ = b;
        bs->buf = 0;
        bs->pos -= 32;
    }
}
예제 #18
0
/*	flush the bitstream & return length (unit bytes)
	NOTE: assumes no futher bitstream functions will be called.
 */
uint32
BitstreamLength(Bitstream * const bs)
{
    uint32  len = (uint32) bs->tail - (uint32) bs->start;

    if (bs->pos)
    {
        uint32  b = bs->buf;
#ifndef ARCH_IS_BIG_ENDIAN
        BSWAP(b);
#endif
        *bs->tail = b;

        len += (bs->pos + 7) / 8;
    }

    return len;
}
예제 #19
0
/* skip n bits forward in bitstream */
void
BitstreamSkip(Bitstream * const bs, const uint32 bits)
{
    bs->pos += bits;

    if (bs->pos >= 32)
    {
        uint32  tmp;

        bs->bufa = bs->bufb;
        tmp = *((uint32 *) bs->tail + 2);

#ifndef ARCH_IS_BIG_ENDIAN
        BSWAP(tmp);
#endif
        bs->bufb = tmp;
        bs->tail++;
        bs->pos -= 32;
    }
}
예제 #20
0
파일: biniku.c 프로젝트: amayra/arc_conv
static int biniku_jmp(FILE *fi, uint *m, uint x) {
	uint a, i = 1;
	*m = i;
	for(;;) {
	  if((a = fgetc(fi)) == EOF) break;
	  switch(biniku_code(a)) {

	  case 1:	  // offset
	    READ(&a, 4);
	    if(i == x) break;
	    if(x) m[i] = BSWAP(a); i++; *m = i;
	    break;

	  case 2:	  // int
	    READ(&a, 4);
	    break;

	  case 3:	  // string
	    do LODSB; while(a);
	    break;
	  }
	}
	return 0;
}
예제 #21
0
/*
 * Function that does the real stuff.
 */
bpf_filter_func
bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size)
{
	bpf_bin_stream stream;
	struct bpf_insn *ins;
	int flags, fret, fpkt, fmem, fjmp, flen;
	u_int i, pass;

	/*
	 * NOTE: Do not modify the name of this variable, as it's used by
	 * the macros to emit code.
	 */
	emit_func emitm;

	flags = bpf_jit_optimize(prog, nins);
	fret = (flags & BPF_JIT_FRET) != 0;
	fpkt = (flags & BPF_JIT_FPKT) != 0;
	fmem = (flags & BPF_JIT_FMEM) != 0;
	fjmp = (flags & BPF_JIT_FJMP) != 0;
	flen = (flags & BPF_JIT_FLEN) != 0;

	if (fret)
		nins = 1;

	memset(&stream, 0, sizeof(stream));

	/* Allocate the reference table for the jumps. */
	if (fjmp) {
#ifdef _KERNEL
		stream.refs = malloc((nins + 1) * sizeof(u_int), M_BPFJIT,
		    M_NOWAIT | M_ZERO);
#else
		stream.refs = calloc(nins + 1, sizeof(u_int));
#endif
		if (stream.refs == NULL)
			return (NULL);
	}

	/*
	 * The first pass will emit the lengths of the instructions
	 * to create the reference table.
	 */
	emitm = emit_length;

	for (pass = 0; pass < 2; pass++) {
		ins = prog;

		/* Create the procedure header. */
		if (fmem) {
			PUSH(RBP);
			MOVrq(RSP, RBP);
			SUBib(BPF_MEMWORDS * sizeof(uint32_t), RSP);
		}
		if (flen)
			MOVrd2(ESI, R9D);
		if (fpkt) {
			MOVrq2(RDI, R8);
			MOVrd(EDX, EDI);
		}

		for (i = 0; i < nins; i++) {
			stream.bpf_pc++;

			switch (ins->code) {
			default:
#ifdef _KERNEL
				return (NULL);
#else
				abort();
#endif

			case BPF_RET|BPF_K:
				MOVid(ins->k, EAX);
				if (fmem)
					LEAVE();
				RET();
				break;

			case BPF_RET|BPF_A:
				if (fmem)
					LEAVE();
				RET();
				break;

			case BPF_LD|BPF_W|BPF_ABS:
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				JAb(12);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int32_t), ECX);
				if (fmem) {
					JAEb(4);
					ZEROrd(EAX);
					LEAVE();
				} else {
					JAEb(3);
					ZEROrd(EAX);
				}
				RET();
				MOVrq3(R8, RCX);
				MOVobd(RCX, RSI, EAX);
				BSWAP(EAX);
				break;

			case BPF_LD|BPF_H|BPF_ABS:
				ZEROrd(EAX);
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				JAb(12);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int16_t), ECX);
				if (fmem) {
					JAEb(2);
					LEAVE();
				} else
					JAEb(1);
				RET();
				MOVrq3(R8, RCX);
				MOVobw(RCX, RSI, AX);
				SWAP_AX();
				break;

			case BPF_LD|BPF_B|BPF_ABS:
				ZEROrd(EAX);
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				if (fmem) {
					JBb(2);
					LEAVE();
				} else
					JBb(1);
				RET();
				MOVrq3(R8, RCX);
				MOVobb(RCX, RSI, AL);
				break;

			case BPF_LD|BPF_W|BPF_LEN:
				MOVrd3(R9D, EAX);
				break;

			case BPF_LDX|BPF_W|BPF_LEN:
				MOVrd3(R9D, EDX);
				break;

			case BPF_LD|BPF_W|BPF_IND:
				CMPrd(EDI, EDX);
				JAb(27);
				MOVid(ins->k, ESI);
				MOVrd(EDI, ECX);
				SUBrd(EDX, ECX);
				CMPrd(ESI, ECX);
				JBb(14);
				ADDrd(EDX, ESI);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int32_t), ECX);
				if (fmem) {
					JAEb(4);
					ZEROrd(EAX);
					LEAVE();
				} else {
					JAEb(3);
					ZEROrd(EAX);
				}
				RET();
				MOVrq3(R8, RCX);
				MOVobd(RCX, RSI, EAX);
				BSWAP(EAX);
				break;

			case BPF_LD|BPF_H|BPF_IND:
				ZEROrd(EAX);
				CMPrd(EDI, EDX);
				JAb(27);
				MOVid(ins->k, ESI);
				MOVrd(EDI, ECX);
				SUBrd(EDX, ECX);
				CMPrd(ESI, ECX);
				JBb(14);
				ADDrd(EDX, ESI);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int16_t), ECX);
				if (fmem) {
					JAEb(2);
					LEAVE();
				} else
					JAEb(1);
				RET();
				MOVrq3(R8, RCX);
				MOVobw(RCX, RSI, AX);
				SWAP_AX();
				break;

			case BPF_LD|BPF_B|BPF_IND:
				ZEROrd(EAX);
				CMPrd(EDI, EDX);
				JAEb(13);
				MOVid(ins->k, ESI);
				MOVrd(EDI, ECX);
				SUBrd(EDX, ECX);
				CMPrd(ESI, ECX);
				if (fmem) {
					JAb(2);
					LEAVE();
				} else
					JAb(1);
				RET();
				MOVrq3(R8, RCX);
				ADDrd(EDX, ESI);
				MOVobb(RCX, RSI, AL);
				break;

			case BPF_LDX|BPF_MSH|BPF_B:
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				if (fmem) {
					JBb(4);
					ZEROrd(EAX);
					LEAVE();
				} else {
					JBb(3);
					ZEROrd(EAX);
				}
				RET();
				ZEROrd(EDX);
				MOVrq3(R8, RCX);
				MOVobb(RCX, RSI, DL);
				ANDib(0x0f, DL);
				SHLib(2, EDX);
				break;

			case BPF_LD|BPF_IMM:
				MOVid(ins->k, EAX);
				break;

			case BPF_LDX|BPF_IMM:
				MOVid(ins->k, EDX);
				break;

			case BPF_LD|BPF_MEM:
				MOVid(ins->k * sizeof(uint32_t), ESI);
				MOVobd(RSP, RSI, EAX);
				break;

			case BPF_LDX|BPF_MEM:
				MOVid(ins->k * sizeof(uint32_t), ESI);
				MOVobd(RSP, RSI, EDX);
				break;

			case BPF_ST:
				/*
				 * XXX this command and the following could
				 * be optimized if the previous instruction
				 * was already of this type
				 */
				MOVid(ins->k * sizeof(uint32_t), ESI);
				MOVomd(EAX, RSP, RSI);
				break;

			case BPF_STX:
				MOVid(ins->k * sizeof(uint32_t), ESI);
				MOVomd(EDX, RSP, RSI);
				break;

			case BPF_JMP|BPF_JA:
				JUMP(ins->k);
				break;

			case BPF_JMP|BPF_JGT|BPF_K:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				CMPid(ins->k, EAX);
				JCC(JA, JBE);
				break;

			case BPF_JMP|BPF_JGE|BPF_K:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				CMPid(ins->k, EAX);
				JCC(JAE, JB);
				break;

			case BPF_JMP|BPF_JEQ|BPF_K:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				CMPid(ins->k, EAX);
				JCC(JE, JNE);
				break;

			case BPF_JMP|BPF_JSET|BPF_K:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				TESTid(ins->k, EAX);
				JCC(JNE, JE);
				break;

			case BPF_JMP|BPF_JGT|BPF_X:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				CMPrd(EDX, EAX);
				JCC(JA, JBE);
				break;

			case BPF_JMP|BPF_JGE|BPF_X:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				CMPrd(EDX, EAX);
				JCC(JAE, JB);
				break;

			case BPF_JMP|BPF_JEQ|BPF_X:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				CMPrd(EDX, EAX);
				JCC(JE, JNE);
				break;

			case BPF_JMP|BPF_JSET|BPF_X:
				if (ins->jt == ins->jf) {
					JUMP(ins->jt);
					break;
				}
				TESTrd(EDX, EAX);
				JCC(JNE, JE);
				break;

			case BPF_ALU|BPF_ADD|BPF_X:
				ADDrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_SUB|BPF_X:
				SUBrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_MUL|BPF_X:
				MOVrd(EDX, ECX);
				MULrd(EDX);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_DIV|BPF_X:
				TESTrd(EDX, EDX);
				if (fmem) {
					JNEb(4);
					ZEROrd(EAX);
					LEAVE();
				} else {
					JNEb(3);
					ZEROrd(EAX);
				}
				RET();
				MOVrd(EDX, ECX);
				ZEROrd(EDX);
				DIVrd(ECX);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_AND|BPF_X:
				ANDrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_OR|BPF_X:
				ORrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_LSH|BPF_X:
				MOVrd(EDX, ECX);
				SHL_CLrb(EAX);
				break;

			case BPF_ALU|BPF_RSH|BPF_X:
				MOVrd(EDX, ECX);
				SHR_CLrb(EAX);
				break;

			case BPF_ALU|BPF_ADD|BPF_K:
				ADD_EAXi(ins->k);
				break;

			case BPF_ALU|BPF_SUB|BPF_K:
				SUB_EAXi(ins->k);
				break;

			case BPF_ALU|BPF_MUL|BPF_K:
				MOVrd(EDX, ECX);
				MOVid(ins->k, EDX);
				MULrd(EDX);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_DIV|BPF_K:
				MOVrd(EDX, ECX);
				ZEROrd(EDX);
				MOVid(ins->k, ESI);
				DIVrd(ESI);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_AND|BPF_K:
				ANDid(ins->k, EAX);
				break;

			case BPF_ALU|BPF_OR|BPF_K:
				ORid(ins->k, EAX);
				break;

			case BPF_ALU|BPF_LSH|BPF_K:
				SHLib((ins->k) & 0xff, EAX);
				break;

			case BPF_ALU|BPF_RSH|BPF_K:
				SHRib((ins->k) & 0xff, EAX);
				break;

			case BPF_ALU|BPF_NEG:
				NEGd(EAX);
				break;

			case BPF_MISC|BPF_TAX:
				MOVrd(EAX, EDX);
				break;

			case BPF_MISC|BPF_TXA:
				MOVrd(EDX, EAX);
				break;
			}
			ins++;
		}

		if (pass > 0)
			continue;

		*size = stream.cur_ip;
#ifdef _KERNEL
		stream.ibuf = malloc(*size, M_BPFJIT, M_NOWAIT);
		if (stream.ibuf == NULL)
			break;
#else
		stream.ibuf = mmap(NULL, *size, PROT_READ | PROT_WRITE,
		    MAP_ANON, -1, 0);
		if (stream.ibuf == MAP_FAILED) {
			stream.ibuf = NULL;
			break;
		}
#endif

		/*
		 * Modify the reference table to contain the offsets and
		 * not the lengths of the instructions.
		 */
		if (fjmp)
			for (i = 1; i < nins + 1; i++)
				stream.refs[i] += stream.refs[i - 1];

		/* Reset the counters. */
		stream.cur_ip = 0;
		stream.bpf_pc = 0;

		/* The second pass creates the actual code. */
		emitm = emit_code;
	}

	/*
	 * The reference table is needed only during compilation,
	 * now we can free it.
	 */
	if (fjmp)
#ifdef _KERNEL
		free(stream.refs, M_BPFJIT);
#else
		free(stream.refs);
#endif

#ifndef _KERNEL
	if (stream.ibuf != NULL &&
	    mprotect(stream.ibuf, *size, PROT_READ | PROT_EXEC) != 0) {
		munmap(stream.ibuf, *size);
		stream.ibuf = NULL;
	}
#endif

	return ((bpf_filter_func)stream.ibuf);
}
예제 #22
0
void BSWAP( LONG* ptr ){ BSWAP( ptr, 4 ); }
예제 #23
0
void BSWAP( int* ptr ){ BSWAP( ptr, 4 ); }
예제 #24
0
/*
 * Function that does the real stuff
 */
bpf_filter_func
bpf_jit_compile(struct bpf_insn *prog, u_int nins, int *mem)
{
	struct bpf_insn *ins;
	u_int i, pass;
	bpf_bin_stream stream;

	/*
	 * NOTE: do not modify the name of this variable, as it's used by
	 * the macros to emit code.
	 */
	emit_func emitm;

	/* Allocate the reference table for the jumps */
#ifdef _KERNEL
	stream.refs = (u_int *)malloc((nins + 1) * sizeof(u_int),
	    M_BPFJIT, M_NOWAIT);
#else
	stream.refs = (u_int *)malloc((nins + 1) * sizeof(u_int));
#endif
	if (stream.refs == NULL)
		return (NULL);

	/* Reset the reference table */
	for (i = 0; i < nins + 1; i++)
		stream.refs[i] = 0;

	stream.cur_ip = 0;
	stream.bpf_pc = 0;

	/*
	 * the first pass will emit the lengths of the instructions
	 * to create the reference table
	 */
	emitm = emit_length;

	pass = 0;
	for (;;) {
		ins = prog;

		/* create the procedure header */
		MOVrq2(RBX, R8);
		MOVrq(RDI, RBX);
		MOVrd2(ESI, R9D);
		MOVrd(EDX, EDI);

		for (i = 0; i < nins; i++) {
			stream.bpf_pc++;

			switch (ins->code) {
			default:
#ifdef _KERNEL
				return (NULL);
#else
				abort();
#endif

			case BPF_RET|BPF_K:
				MOVid(ins->k, EAX);
				MOVrq3(R8, RBX);
				RET();
				break;

			case BPF_RET|BPF_A:
				MOVrq3(R8, RBX);
				RET();
				break;

			case BPF_LD|BPF_W|BPF_ABS:
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				JAb(12);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int32_t), ECX);
				JAEb(6);
				ZEROrd(EAX);
				MOVrq3(R8, RBX);
				RET();
				MOVobd(RBX, RSI, EAX);
				BSWAP(EAX);
				break;

			case BPF_LD|BPF_H|BPF_ABS:
				ZEROrd(EAX);
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				JAb(12);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int16_t), ECX);
				JAEb(4);
				MOVrq3(R8, RBX);
				RET();
				MOVobw(RBX, RSI, AX);
				SWAP_AX();
				break;

			case BPF_LD|BPF_B|BPF_ABS:
				ZEROrd(EAX);
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				JBb(4);
				MOVrq3(R8, RBX);
				RET();
				MOVobb(RBX, RSI, AL);
				break;

			case BPF_LD|BPF_W|BPF_LEN:
				MOVrd3(R9D, EAX);
				break;

			case BPF_LDX|BPF_W|BPF_LEN:
				MOVrd3(R9D, EDX);
				break;

			case BPF_LD|BPF_W|BPF_IND:
				CMPrd(EDI, EDX);
				JAb(27);
				MOVid(ins->k, ESI);
				MOVrd(EDI, ECX);
				SUBrd(EDX, ECX);
				CMPrd(ESI, ECX);
				JBb(14);
				ADDrd(EDX, ESI);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int32_t), ECX);
				JAEb(6);
				ZEROrd(EAX);
				MOVrq3(R8, RBX);
				RET();
				MOVobd(RBX, RSI, EAX);
				BSWAP(EAX);
				break;

			case BPF_LD|BPF_H|BPF_IND:
				ZEROrd(EAX);
				CMPrd(EDI, EDX);
				JAb(27);
				MOVid(ins->k, ESI);
				MOVrd(EDI, ECX);
				SUBrd(EDX, ECX);
				CMPrd(ESI, ECX);
				JBb(14);
				ADDrd(EDX, ESI);
				MOVrd(EDI, ECX);
				SUBrd(ESI, ECX);
				CMPid(sizeof(int16_t), ECX);
				JAEb(4);
				MOVrq3(R8, RBX);
				RET();
				MOVobw(RBX, RSI, AX);
				SWAP_AX();
				break;

			case BPF_LD|BPF_B|BPF_IND:
				ZEROrd(EAX);
				CMPrd(EDI, EDX);
				JAEb(13);
				MOVid(ins->k, ESI);
				MOVrd(EDI, ECX);
				SUBrd(EDX, ECX);
				CMPrd(ESI, ECX);
				JAb(4);
				MOVrq3(R8, RBX);
				RET();
				ADDrd(EDX, ESI);
				MOVobb(RBX, RSI, AL);
				break;

			case BPF_LDX|BPF_MSH|BPF_B:
				MOVid(ins->k, ESI);
				CMPrd(EDI, ESI);
				JBb(6);
				ZEROrd(EAX);
				MOVrq3(R8, RBX);
				RET();
				ZEROrd(EDX);
				MOVobb(RBX, RSI, DL);
				ANDib(0x0f, DL);
				SHLib(2, EDX);
				break;

			case BPF_LD|BPF_IMM:
				MOVid(ins->k, EAX);
				break;

			case BPF_LDX|BPF_IMM:
				MOVid(ins->k, EDX);
				break;

			case BPF_LD|BPF_MEM:
				MOViq((uintptr_t)mem, RCX);
				MOVid(ins->k * 4, ESI);
				MOVobd(RCX, RSI, EAX);
				break;

			case BPF_LDX|BPF_MEM:
				MOViq((uintptr_t)mem, RCX);
				MOVid(ins->k * 4, ESI);
				MOVobd(RCX, RSI, EDX);
				break;

			case BPF_ST:
				/*
				 * XXX this command and the following could
				 * be optimized if the previous instruction
				 * was already of this type
				 */
				MOViq((uintptr_t)mem, RCX);
				MOVid(ins->k * 4, ESI);
				MOVomd(EAX, RCX, RSI);
				break;

			case BPF_STX:
				MOViq((uintptr_t)mem, RCX);
				MOVid(ins->k * 4, ESI);
				MOVomd(EDX, RCX, RSI);
				break;

			case BPF_JMP|BPF_JA:
				JMP(stream.refs[stream.bpf_pc + ins->k] -
				    stream.refs[stream.bpf_pc]);
				break;

			case BPF_JMP|BPF_JGT|BPF_K:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				CMPid(ins->k, EAX);
				JCC(JA, JBE);
				break;

			case BPF_JMP|BPF_JGE|BPF_K:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				CMPid(ins->k, EAX);
				JCC(JAE, JB);
				break;

			case BPF_JMP|BPF_JEQ|BPF_K:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				CMPid(ins->k, EAX);
				JCC(JE, JNE);
				break;

			case BPF_JMP|BPF_JSET|BPF_K:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				TESTid(ins->k, EAX);
				JCC(JNE, JE);
				break;

			case BPF_JMP|BPF_JGT|BPF_X:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				CMPrd(EDX, EAX);
				JCC(JA, JBE);
				break;

			case BPF_JMP|BPF_JGE|BPF_X:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				CMPrd(EDX, EAX);
				JCC(JAE, JB);
				break;

			case BPF_JMP|BPF_JEQ|BPF_X:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				CMPrd(EDX, EAX);
				JCC(JE, JNE);
				break;

			case BPF_JMP|BPF_JSET|BPF_X:
				if (ins->jt == 0 && ins->jf == 0)
					break;
				TESTrd(EDX, EAX);
				JCC(JNE, JE);
				break;

			case BPF_ALU|BPF_ADD|BPF_X:
				ADDrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_SUB|BPF_X:
				SUBrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_MUL|BPF_X:
				MOVrd(EDX, ECX);
				MULrd(EDX);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_DIV|BPF_X:
				TESTrd(EDX, EDX);
				JNEb(6);
				ZEROrd(EAX);
				MOVrq3(R8, RBX);
				RET();
				MOVrd(EDX, ECX);
				ZEROrd(EDX);
				DIVrd(ECX);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_AND|BPF_X:
				ANDrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_OR|BPF_X:
				ORrd(EDX, EAX);
				break;

			case BPF_ALU|BPF_LSH|BPF_X:
				MOVrd(EDX, ECX);
				SHL_CLrb(EAX);
				break;

			case BPF_ALU|BPF_RSH|BPF_X:
				MOVrd(EDX, ECX);
				SHR_CLrb(EAX);
				break;

			case BPF_ALU|BPF_ADD|BPF_K:
				ADD_EAXi(ins->k);
				break;

			case BPF_ALU|BPF_SUB|BPF_K:
				SUB_EAXi(ins->k);
				break;

			case BPF_ALU|BPF_MUL|BPF_K:
				MOVrd(EDX, ECX);
				MOVid(ins->k, EDX);
				MULrd(EDX);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_DIV|BPF_K:
				MOVrd(EDX, ECX);
				ZEROrd(EDX);
				MOVid(ins->k, ESI);
				DIVrd(ESI);
				MOVrd(ECX, EDX);
				break;

			case BPF_ALU|BPF_AND|BPF_K:
				ANDid(ins->k, EAX);
				break;

			case BPF_ALU|BPF_OR|BPF_K:
				ORid(ins->k, EAX);
				break;

			case BPF_ALU|BPF_LSH|BPF_K:
				SHLib((ins->k) & 0xff, EAX);
				break;

			case BPF_ALU|BPF_RSH|BPF_K:
				SHRib((ins->k) & 0xff, EAX);
				break;

			case BPF_ALU|BPF_NEG:
				NEGd(EAX);
				break;

			case BPF_MISC|BPF_TAX:
				MOVrd(EAX, EDX);
				break;

			case BPF_MISC|BPF_TXA:
				MOVrd(EDX, EAX);
				break;
			}
			ins++;
		}

		pass++;
		if (pass == 2)
			break;

#ifdef _KERNEL
		stream.ibuf = (char *)malloc(stream.cur_ip, M_BPFJIT, M_NOWAIT);
		if (stream.ibuf == NULL) {
			free(stream.refs, M_BPFJIT);
			return (NULL);
		}
#else
		stream.ibuf = (char *)malloc(stream.cur_ip);
		if (stream.ibuf == NULL) {
			free(stream.refs);
			return (NULL);
		}
#endif

		/*
		 * modify the reference table to contain the offsets and
		 * not the lengths of the instructions
		 */
		for (i = 1; i < nins + 1; i++)
			stream.refs[i] += stream.refs[i - 1];

		/* Reset the counters */
		stream.cur_ip = 0;
		stream.bpf_pc = 0;

		/* the second pass creates the actual code */
		emitm = emit_code;
	}

	/*
	 * the reference table is needed only during compilation,
	 * now we can free it
	 */
#ifdef _KERNEL
	free(stream.refs, M_BPFJIT);
#else
	free(stream.refs);
#endif

	return ((bpf_filter_func)stream.ibuf);
}
예제 #25
0
/*
 * Try to parse object at current cursor position
 * Returns:
 *  NTDS_BAD_RECORD if record is not a user account or computer
 *  NTDS_MEM_ERROR if memory allocation errors
 */
int NTDS_NTLM_ParseSAMRecord(s_parser *parser,JET_TABLEID tableid,s_ldapAccountInfo *ldapAccountEntry,BOOL with_history) {
	unsigned long attributeSize;
	BYTE attributeVal[1024];
	JET_ERR jet_err;

	RtlZeroMemory(ldapAccountEntry,sizeof(s_ldapAccountInfo));

	/* Browse per sam account type */
	attributeSize = sizeof(attributeVal);
	jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_SAM_ACCOUNT_TYPE].columnid,attributeVal,&attributeSize);
	if((jet_err==JET_errSuccess)&&(attributeSize==sizeof(ldapAccountEntry->szSAMAccountType))) {
		ldapAccountEntry->szSAMAccountType = *(LPDWORD)attributeVal;
	} 
	else
		return NTDS_BAD_RECORD;

	if((ldapAccountEntry->szSAMAccountType != SAM_USER_OBJECT) && 
		(ldapAccountEntry->szSAMAccountType != SAM_MACHINE_ACCOUNT) && 
		(ldapAccountEntry->szSAMAccountType != SAM_TRUST_ACCOUNT)){
		return NTDS_BAD_RECORD;
	}

	/* Get SAM account name */
	attributeSize = sizeof(attributeVal);
	jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_SAM_ACCOUNT_NAME].columnid,attributeVal,&attributeSize);
	if((!attributeSize) || (jet_err!=JET_errSuccess))
		return NTDS_BAD_RECORD;

	lstrcpyW(ldapAccountEntry->szSAMAccountName,(LPWSTR)attributeVal);


	/* Get LM hash */
	attributeSize = sizeof(attributeVal);
	jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_LM_HASH].columnid,attributeVal,&attributeSize);
	if((jet_err==JET_errSuccess)&&(attributeSize==sizeof(s_NTLM_hash_ciphered))) {
		RtlMoveMemory(&ldapAccountEntry->LM_hash_ciphered,attributeVal,sizeof(s_NTLM_hash_ciphered));
		ldapAccountEntry->NTLM_hash.hash_type = LM_HASH;
	}
	else {
		ldapAccountEntry->NTLM_hash.hash_type = NT_NO_HASH;
	}

	/* Get NT hash */
	attributeSize = sizeof(attributeVal);
	jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_NT_HASH].columnid,attributeVal,&attributeSize);
	if((jet_err==JET_errSuccess)&&(attributeSize==sizeof(s_NTLM_hash_ciphered))) {
		RtlMoveMemory(&ldapAccountEntry->NT_hash_ciphered,attributeVal,sizeof(s_NTLM_hash_ciphered));
		if(ldapAccountEntry->NTLM_hash.hash_type != LM_HASH)
			ldapAccountEntry->NTLM_hash.hash_type = NT_HASH;
	}

	if(with_history) {
		/* Get LM hash history */
		jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_LM_HASH_HISTORY].columnid,NULL,&attributeSize);
		if(jet_err==JET_errSuccess && attributeSize) {
			ldapAccountEntry->LM_history_ciphered = (LPBYTE)VirtualAlloc(NULL,attributeSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
			ldapAccountEntry->LM_history_deciphered = (LPBYTE)VirtualAlloc(NULL,attributeSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
			if(!ldapAccountEntry->LM_history_ciphered || !ldapAccountEntry->LM_history_deciphered)
				return NTDS_MEM_ERROR;
			jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_LM_HASH_HISTORY].columnid,ldapAccountEntry->LM_history_ciphered,&attributeSize);
			if(jet_err != JET_errSuccess)
				return NTDS_API_ERROR;
			ldapAccountEntry->LM_history_ciphered_size = attributeSize;
		}
		
		/* Get NT hash history */
		jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_NT_HASH_HISTORY].columnid,NULL,&attributeSize);
		if(jet_err==JET_errSuccess && attributeSize) {
			ldapAccountEntry->NT_history_ciphered = (LPBYTE)VirtualAlloc(NULL,attributeSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
			ldapAccountEntry->NT_history_deciphered = (LPBYTE)VirtualAlloc(NULL,attributeSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
			if(!ldapAccountEntry->NT_history_ciphered || !ldapAccountEntry->NT_history_deciphered)
				return NTDS_MEM_ERROR;
			jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_NT_HASH_HISTORY].columnid,ldapAccountEntry->NT_history_ciphered,&attributeSize);
			if(jet_err != JET_errSuccess)
				return NTDS_API_ERROR;
		}

		if(ldapAccountEntry->LM_history_ciphered && ldapAccountEntry->NT_history_ciphered) {
			ldapAccountEntry->nbHistoryEntries = (attributeSize - 24) / WIN_NTLM_HASH_SIZE;
			if(!(ldapAccountEntry->NTLM_hash_history = (s_NTLM_Hash *)VirtualAlloc(NULL,ldapAccountEntry->nbHistoryEntries*sizeof(s_NTLM_Hash),MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE)))
				return NTDS_MEM_ERROR;
			ldapAccountEntry->NT_history_ciphered_size = attributeSize;
		}
	}

	/* Get Sid */
	attributeSize = sizeof(attributeVal);
	jet_err = NTDS_GetRecord(parser,tableid,parser->columndef[ID_OBJECT_SID].columnid,attributeVal,&attributeSize);
	if(jet_err==JET_errSuccess) {
		ldapAccountEntry->sid = (PSID)VirtualAlloc(NULL,attributeSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
		if(!ldapAccountEntry->sid)
			return NTDS_MEM_ERROR;
		RtlMoveMemory(ldapAccountEntry->sid,attributeVal,attributeSize-sizeof(ldapAccountEntry->rid));
		ldapAccountEntry->rid = BSWAP(*LPDWORD(attributeVal+attributeSize-sizeof(ldapAccountEntry->rid)));
		*LPDWORD((LPBYTE)ldapAccountEntry->sid+attributeSize-sizeof(ldapAccountEntry->rid))= ldapAccountEntry->rid;
	}
	else
		return NTDS_BAD_RECORD;

	return NTDS_SUCCESS;
}
예제 #26
0
void ESWAP( WORD* ptr, bool doSwap ){ if (doSwap) BSWAP( ptr, 2 ); }
예제 #27
0
void ESWAP( DWORD* ptr, bool doSwap ){ if (doSwap) BSWAP( ptr, 4 ); }
void HashSHA1Block(void* hash_block, SHA1_Context* ctx)
{
	unsigned int a,b,c,d,e,T,i;
	unsigned char* block = (unsigned char*)hash_block;
	unsigned int w[0x50];
	a = ctx->h0;
	b = ctx->h1;
	c = ctx->h2;
	d = ctx->h3;
	e = ctx->h4;
	for (i = 0; i < 16; i++) w[i] = BSWAP(*(unsigned int*)(block + i * 4));
	for (i = 16; i < 80; i++) w[i] = ROTL( w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
	
	for (i = 0; i < 20; i++)
	{
		T = ROTL(a,5) + Ch(b,c,d) + e + sha1_constant[0] + w[i];
		e = d;
		d = c;
		c = ROTL(b,30);
		b = a;
		a = T;

	}
	for (i=20;i<40;i++)
	{
		T = ROTL(a,5) + Parity(b,c,d) + e + sha1_constant[1] + w[i];
		e = d;
		d = c;
		c = ROTL(b,30);
		b = a;
		a = T;

	}
	for (i=40;i<60;i++)
	{
		T = ROTL(a,5) + Maj(b,c,d) + e + sha1_constant[2] + w[i];
		e = d;
		d = c;
		c = ROTL(b,30);
		b = a;
		a = T;

	}
	for (i=60;i<80;i++)
	{
		T = ROTL(a,5) + Parity(b,c,d) + e + sha1_constant[3] + w[i];
		e = d;
		d = c;
		c = ROTL(b,30);
		b = a;
		a = T;

	}

	ctx->h0 += a;
	ctx->h1 += b;
	ctx->h2 += c;
	ctx->h3 += d;
	ctx->h4 += e;
	a = b = c = d = e = T = 0;
	memset(w, 0, 0x140);
}
예제 #29
0
void ESWAP( LONG* ptr, bool doSwap ){ if (doSwap) BSWAP( ptr, 4 ); }
예제 #30
0
void ESWAP( int* ptr, bool doSwap ){ if (doSwap) BSWAP( ptr, 4 ); }