Ejemplo n.º 1
0
Archivo: sc.c Proyecto: adrianc-a/scfs
sc_track_t *sc_track_from_json(cJSON *json) {
    if (!cJSON_GetObjectItem(json, "streamable")->valueint) {
        return NULL;
    }

    char *id;
    I_TO_A(cJSON_GetObjectItem(json, "id")->valueint, id);
    char *title = cJSON_GetObjectItem(json, "title")->valuestring;

    size_t o_size = (size_t)cJSON_GetObjectItem(json, 
            "original_content_size")->valueint;

    buf_t tmp = {
        .size = o_size,
        .data = NULL,
        .allocated = 0
    };

    sc_track_t *ret = sc_track_new(id, title, &tmp);
    free(id);
    return ret;
}

void sc_track_cpy(sc_track_t *dst, sc_track_t *src) {

    dst->title = strdup(src->title);
    dst->id = strdup(src->id);
    dst->data = malloc(sizeof(buf_t));
    buf_cpy(dst->data, src->data);
}
Ejemplo n.º 2
0
/**
 * Copy a struct scan_field for insertion into the queue.
 *
 * This allocates a new copy of out_value using cmd_queue_alloc.
 */
static void cmd_queue_scan_field_clone(struct scan_field * dst, const struct scan_field * src)
{
	dst->tap		= src->tap;
	dst->num_bits	= src->num_bits;
	dst->out_value	= buf_cpy(src->out_value, cmd_queue_alloc(DIV_ROUND_UP(src->num_bits, 8)), src->num_bits);
	dst->in_value	= src->in_value;
}
Ejemplo n.º 3
0
Archivo: sc.c Proyecto: adrianc-a/scfs
sc_track_t *sc_track_new(char *i, char *t, buf_t *contents) {
    sc_track_t *ret = malloc(sizeof(sc_track_t));
    ret->id = strdup(i);
    ret->title = strdup(t);
    ret->data = malloc(sizeof(buf_t));
    buf_cpy(ret->data, contents);

    return ret;
}
Ejemplo n.º 4
0
int main()
{
    int n;
    int upper;
    char src_buf[1024];
    char dst_buf[1024];
    
    printf("Please input sum: ");
    scanf("%d", &upper);
    calc_sum(&n, upper);

    gen_random(src_buf, sizeof(src_buf));
    /* Copy to local buffer */
    buf_cpy(dst_buf, src_buf, sizeof(dst_buf));
    /* Copy to global buffer */
    buf_cpy(g_buf, src_buf, sizeof(g_buf));

    return 0;
}
Ejemplo n.º 5
0
static gcry_err_code_t
hmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
{
  unsigned int dlen;
  const unsigned char *digest;

  dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
  digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);

  if (*outlen <= dlen)
    buf_cpy (outbuf, digest, *outlen);
  else
    {
      buf_cpy (outbuf, digest, dlen);
      *outlen = dlen;
    }

  return 0;
}
Ejemplo n.º 6
0
/**
 * see jtag_add_ir_scan()
 *
 */
int interface_jtag_add_ir_scan(struct jtag_tap* active, const struct scan_field *in_fields, tap_state_t state)
{
	size_t num_taps = jtag_tap_count_enabled();

	struct jtag_command * cmd		= cmd_queue_alloc(sizeof(struct jtag_command));
	struct scan_command * scan		= cmd_queue_alloc(sizeof(struct scan_command));
	struct scan_field * out_fields	= cmd_queue_alloc(num_taps  * sizeof(struct scan_field));

	jtag_queue_command(cmd);

	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;

	scan->ir_scan			= true;
	scan->num_fields		= num_taps;	/* one field per device */
	scan->fields			= out_fields;
	scan->end_state			= state;


	struct scan_field * field = out_fields;	/* keep track where we insert data */

	/* loop over all enabled TAPs */

	for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
	{
		/* search the input field list for fields for the current TAP */

		if (tap == active)
		{
			/* if TAP is listed in input fields, copy the value */
			tap->bypass = 0;

			cmd_queue_scan_field_clone(field, in_fields);
		} else
		{
			/* if a TAP isn't listed in input fields, set it to BYPASS */

			tap->bypass = 1;

			field->num_bits		= tap->ir_length;
			field->out_value	= buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);
			field->in_value		= NULL; /* do not collect input for tap's in bypass */
		}

		/* update device information */
		buf_cpy(field->out_value, tap->cur_instr, tap->ir_length);

		field++;
	}

	assert(field == out_fields + num_taps); /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */

	return ERROR_OK;
}
Ejemplo n.º 7
0
static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf)
{
	struct arm_reg *armv7m_reg = reg->arch_info;
	struct target *target = armv7m_reg->target;

	if (target->state != TARGET_HALTED)
		return ERROR_TARGET_NOT_HALTED;

	buf_cpy(buf, reg->value, reg->size);
	reg->dirty = 1;
	reg->valid = 1;

	return ERROR_OK;
}
Ejemplo n.º 8
0
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)
{
	int i;
	int bit_count = 0;
	int retval;

	/* we return ERROR_OK, unless a check fails, or a handler reports a problem */
	retval = ERROR_OK;

	for (i = 0; i < cmd->num_fields; i++)
	{
		/* if neither in_value nor in_handler
		 * are specified we don't have to examine this field
		 */
		if (cmd->fields[i].in_value)
		{
			int num_bits = cmd->fields[i].num_bits;
			uint8_t *captured = buf_set_buf(buffer, bit_count, malloc(DIV_ROUND_UP(num_bits, 8)), 0, num_bits);

#ifdef _DEBUG_JTAG_IO_
			char *char_buf = buf_to_str(captured,
					(num_bits > DEBUG_JTAG_IOZ)
						? DEBUG_JTAG_IOZ
						: num_bits, 16);

			LOG_DEBUG("fields[%i].in_value[%i]: 0x%s",
					i, num_bits, char_buf);
			free(char_buf);
#endif

			if (cmd->fields[i].in_value)
			{
				buf_cpy(captured, cmd->fields[i].in_value, num_bits);
			}

			free(captured);
		}
		bit_count += cmd->fields[i].num_bits;
	}

	return retval;
}
Ejemplo n.º 9
0
static int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits,
		uint8_t *in_bits, tap_state_t state, bool ir_scan)
{
	struct jtag_command * cmd		= cmd_queue_alloc(sizeof(struct jtag_command));
	struct scan_command * scan		= cmd_queue_alloc(sizeof(struct scan_command));
	struct scan_field * out_fields	= cmd_queue_alloc(sizeof(struct scan_field));

	jtag_queue_command(cmd);

	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;

	scan->ir_scan			= ir_scan;
	scan->num_fields		= 1;
	scan->fields			= out_fields;
	scan->end_state			= state;

	out_fields->num_bits	= num_bits;
	out_fields->out_value	= buf_cpy(out_bits, cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
	out_fields->in_value	= in_bits;

	return ERROR_OK;
}
Ejemplo n.º 10
0
int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)
{
	struct jtag_command *cmd;

	cmd = cmd_queue_alloc(sizeof(struct jtag_command));
	if (cmd == NULL)
		return ERROR_FAIL;

	cmd->type = JTAG_TMS;
	cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms));
	if (!cmd->cmd.tms)
		return ERROR_FAIL;

	/* copy the bits; our caller doesn't guarantee they'll persist */
	cmd->cmd.tms->num_bits = num_bits;
	cmd->cmd.tms->bits = buf_cpy(seq,
			cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
	if (!cmd->cmd.tms->bits)
		return ERROR_FAIL;

	jtag_queue_command(cmd);

	return ERROR_OK;
}
Ejemplo n.º 11
0
/**
 * Generate a DR SCAN using the array of output values passed to the function
 *
 * This function assumes that the parameter target_tap specifies the one TAP
 * that is not bypassed. All other TAPs must be bypassed and the function will
 * generate a dummy 1bit field for them.
 *
 * For the target_tap a sequence of output-only fields will be generated where
 * each field has the size num_bits and the field's values are taken from
 * the array value.
 *
 * The bypass status of TAPs is set by jtag_add_ir_scan().
 *
 */
void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
		int in_num_fields,
		const int *num_bits,
		const uint32_t *value,
		tap_state_t end_state)
{
	/* count devices in bypass */

	size_t bypass_devices = 0;

	for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
	{
		if (tap->bypass)
			bypass_devices++;
	}


	struct jtag_command * cmd		= cmd_queue_alloc(sizeof(struct jtag_command));
	struct scan_command * scan		= cmd_queue_alloc(sizeof(struct scan_command));
	struct scan_field * out_fields	= cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field));

	jtag_queue_command(cmd);

	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;

	scan->ir_scan			= false;
	scan->num_fields		= in_num_fields + bypass_devices;
	scan->fields			= out_fields;
	scan->end_state			= end_state;


	bool target_tap_match	= false;

	struct scan_field * field = out_fields;	/* keep track where we insert data */

	/* loop over all enabled TAPs */

	for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
	{
		/* if TAP is not bypassed insert matching input fields */

		if (!tap->bypass)
		{
			assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */

			target_tap_match = true;

			for (int j = 0; j < in_num_fields; j++)
			{
				uint8_t out_value[4];
				size_t scan_size = num_bits[j];
				buf_set_u32(out_value, 0, scan_size, value[j]);

				field->num_bits		= scan_size;
				field->out_value	= buf_cpy(out_value, cmd_queue_alloc(DIV_ROUND_UP(scan_size, 8)), scan_size);
				field->in_value		= NULL;

				field++;
			}
		}

		/* if a TAP is bypassed, generated a dummy bit*/
		else
		{

			field->num_bits			= 1;
			field->out_value		= NULL;
			field->in_value			= NULL;

			field++;
		}
	}

	assert(target_tap_match);	/* target_tap should be enabled and not bypassed */
}
Ejemplo n.º 12
0
static int search_spell(const char *filename, unsigned parnum, unsigned pos)
{
struct	rfc2045	*rfcp, *textp;
struct	buf newtext, current_line;
off_t start_pos, end_pos, start_body;
int	made_replacements, has_misspelling;
char *new_line;
unsigned paragraph;
const char	*ignoreword="";
const char	*replacefrom="";
const char	*replaceto="";
int	checked=0;
off_t	dummy;
FILE	*fp=0;
int	x;

	x=maildir_safeopen(filename, O_RDONLY, 0);
	if (x >= 0)
		if ((fp=fdopen(x, "r")) == 0)
			close(x);

	if (!fp)	return (0);
	rfcp=rfc2045_fromfp(fp);
	if (!rfcp)	enomem();

	textp=findtext(rfcp);

	if (!textp)
	{
		rfc2045_free(rfcp);
		fclose(fp);
		return (0);
	}

	buf_init(&newtext);
	buf_init(&current_line);

        rfc2045_mimepos(textp, &start_pos, &end_pos, &start_body,
		&dummy, &dummy);
        if (fseek(fp, start_body, SEEK_SET) == -1)
                enomem();

	made_replacements=0;
	has_misspelling=0;
	paragraph=0;
        for ( ; start_body < end_pos; start_body++)
	{
	int	c=getc(fp);

		if (c < 0)	enomem();
		if (c != '\n')
		{
			buf_append(&current_line, c);
			continue;
		}
		buf_append(&current_line, '\0');
		if (parnum)
		{
			--parnum;
			buf_cat(&newtext, current_line.ptr);
			buf_cat(&newtext, "\n");
			current_line.cnt=0;
			++paragraph;
			continue;
		}

		if (!checked)
		{
		int	l;

			checked=1;
			if ((l=strlen(cgi("word"))) > 0)
			{

/* Ok, what should we do? */

			const char *newword=cgi("REPLACE");

				if (!*newword || strcmp(newword, "#other") == 0)
					newword=cgi("OTHER");
				/*
				** Perhaps they entered the word without
				** checking this checkmark.
				*/
				else if (*newword == '#')
					newword="";

				if (*newword && pos + l <= strlen(current_line.ptr))
				{
				struct buf tempbuf;

					buf_init(&tempbuf);
					buf_cpyn(&tempbuf, current_line.ptr,
						pos);
					buf_cat(&tempbuf, newword);
					buf_cat(&tempbuf,
						current_line.ptr+pos+l);
					pos += strlen(newword);
					if (*cgi("REPLACEALL"))
					{
						replacefrom=cgi("word");
						replaceto=newword;
					}
					buf_append(&tempbuf, '\0');
					buf_cpy(&current_line, tempbuf.ptr);
					buf_append(&current_line, '\0');
					buf_free(&tempbuf);
					made_replacements=1;
				}
				else
				{
					pos += l;
					if (strcmp(cgi("REPLACE"),
						"#ignoreall") == 0)
						ignoreword=cgi("word");
				}

				if (strcmp(cgi("REPLACE"),
						"#insert") == 0)
				{
					spelladd(cgi("word"));
				}
			}
		}


		if (*current_line.ptr == '>')
		{
			buf_cat(&newtext, current_line.ptr);
			buf_cat(&newtext, "\n");
			pos=0;
			current_line.cnt=0;
			++paragraph;
			continue;
		}
		if (!has_misspelling)
		{
			new_line=spell_check(current_line.ptr, paragraph, pos,
				ignoreword, replacefrom, replaceto,
				&has_misspelling);
			if (new_line)
			{
				buf_cat(&newtext, new_line);
				free(new_line);
				made_replacements=1;
			}
			else	buf_cat(&newtext, current_line.ptr);
		}
		else	buf_cat(&newtext, current_line.ptr);
		buf_cat(&newtext, "\n");
		pos=0;
		current_line.cnt=0;
		++paragraph;
	}
	if (current_line.cnt)
		buf_cat(&newtext, "\n");
	rfc2045_free(rfcp);
	fclose(fp);
	if (made_replacements)
	{
	char	*p=newmsg_createdraft_do(filename, newtext.ptr,
					 NEWMSG_SQISPELL);

		if (p)	free(p);

		if (*cgi("error"))
		{
			has_misspelling=0;	/* Abort spell checking */
		}
	}

	buf_free(&newtext);
	buf_free(&current_line);

	if (*ignoreword)
	{
	static char *p=0;

		if (p)	free(p);
		p=malloc(strlen(cgi("globignore")) + 2 + strlen(ignoreword));

		if (!p)	enomem();

		strcpy(p, cgi("globignore"));
		if (*p)	strcat(p, ":");
		strcat(p, ignoreword);
		cgi_put("globignore", p);
	}

	if (*replacefrom)
	{
	static char *p=0;

		if (p)	free(p);
		p=malloc(strlen(cgi("globreplace"))+3
			+strlen(replacefrom)+strlen(replaceto));

		if (!p)	enomem();
		strcpy(p, cgi("globreplace"));
		if (*p)	strcat(p, ":");
		strcat(strcat(strcat(p, replacefrom), ":"), replaceto);
		cgi_put("globreplace", p);
		free(p);
	}
	if (has_misspelling)	return (1);
	return (0);
}
Ejemplo n.º 13
0
gcry_err_code_t
_gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c,
                          unsigned char *outbuf, size_t outbuflen,
                          const unsigned char *inbuf, size_t inbuflen)
{
  unsigned char *ivp;
  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
  size_t blocksize = c->spec->blocksize;
  size_t blocksize_x_2 = blocksize + blocksize;
  unsigned int burn, nburn;

  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
   * length, to allow better optimization of this function.  */
  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
    return GPG_ERR_INV_LENGTH;

  if (outbuflen < inbuflen)
    return GPG_ERR_BUFFER_TOO_SHORT;

  if ( inbuflen <= c->unused )
    {
      /* Short enough to be encoded by the remaining XOR mask. */
      /* XOR the input with the IV and store input into IV. */
      ivp = c->u_iv.iv + blocksize - c->unused;
      buf_xor_2dst(outbuf, ivp, inbuf, inbuflen);
      c->unused -= inbuflen;
      return 0;
    }

  burn = 0;

  if ( c->unused )
    {
      /* XOR the input with the IV and store input into IV */
      inbuflen -= c->unused;
      ivp = c->u_iv.iv + blocksize - c->unused;
      buf_xor_2dst(outbuf, ivp, inbuf, c->unused);
      outbuf += c->unused;
      inbuf += c->unused;
      c->unused = 0;
    }

  /* Now we can process complete blocks.  We use a loop as long as we
     have at least 2 blocks and use conditions for the rest.  This
     also allows to use a bulk encryption function if available.  */
  if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
    {
      size_t nblocks = inbuflen / blocksize;
      c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
      outbuf += nblocks * blocksize;
      inbuf  += nblocks * blocksize;
      inbuflen -= nblocks * blocksize;
    }
  else
    {
      while ( inbuflen >= blocksize_x_2 )
        {
          /* Encrypt the IV. */
          nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
          burn = nburn > burn ? nburn : burn;
          /* XOR the input with the IV and store input into IV.  */
          buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize);
          outbuf += blocksize;
          inbuf += blocksize;
          inbuflen -= blocksize;
        }
    }

  if ( inbuflen >= blocksize )
    {
      /* Save the current IV and then encrypt the IV. */
      buf_cpy( c->lastiv, c->u_iv.iv, blocksize );
      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
      burn = nburn > burn ? nburn : burn;
      /* XOR the input with the IV and store input into IV */
      buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize);
      outbuf += blocksize;
      inbuf += blocksize;
      inbuflen -= blocksize;
    }
  if ( inbuflen )
    {
      /* Save the current IV and then encrypt the IV. */
      buf_cpy( c->lastiv, c->u_iv.iv, blocksize );
      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
      burn = nburn > burn ? nburn : burn;
      c->unused = blocksize;
      /* Apply the XOR. */
      c->unused -= inbuflen;
      buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, inbuflen);
      outbuf += inbuflen;
      inbuf += inbuflen;
      inbuflen = 0;
    }

  if (burn > 0)
    _gcry_burn_stack (burn + 4 * sizeof(void *));

  return 0;
}
Ejemplo n.º 14
0
gcry_err_code_t
_gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c,
                          unsigned char *outbuf, size_t outbuflen,
                          const unsigned char *inbuf, size_t inbuflen)
{
  size_t n;
  unsigned char *ivp;
  int i;
  size_t blocksize = c->spec->blocksize;
  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
  size_t nblocks = inbuflen / blocksize;
  unsigned int burn, nburn;

  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
   * length, to allow better optimization of this function.  */
  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
    return GPG_ERR_INV_LENGTH;

  if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen))
    return GPG_ERR_BUFFER_TOO_SHORT;

  if ((inbuflen % blocksize)
      && !(inbuflen > blocksize
           && (c->flags & GCRY_CIPHER_CBC_CTS)))
    return GPG_ERR_INV_LENGTH;

  burn = 0;

  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
    {
      if ((inbuflen % blocksize) == 0)
	nblocks--;
    }

  if (c->bulk.cbc_enc)
    {
      c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
                       (c->flags & GCRY_CIPHER_CBC_MAC));
      inbuf  += nblocks * blocksize;
      if (!(c->flags & GCRY_CIPHER_CBC_MAC))
        outbuf += nblocks * blocksize;
    }
  else
    {
      ivp = c->u_iv.iv;

      for (n=0; n < nblocks; n++ )
        {
          buf_xor (outbuf, inbuf, ivp, blocksize);
          nburn = enc_fn ( &c->context.c, outbuf, outbuf );
          burn = nburn > burn ? nburn : burn;
          ivp = outbuf;
          inbuf  += blocksize;
          if (!(c->flags & GCRY_CIPHER_CBC_MAC))
            outbuf += blocksize;
        }

      if (ivp != c->u_iv.iv)
        buf_cpy (c->u_iv.iv, ivp, blocksize );
    }

  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
    {
      /* We have to be careful here, since outbuf might be equal to
         inbuf.  */
      size_t restbytes;
      unsigned char b;

      if ((inbuflen % blocksize) == 0)
        restbytes = blocksize;
      else
        restbytes = inbuflen % blocksize;

      outbuf -= blocksize;
      for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
        {
          b = inbuf[i];
          outbuf[blocksize + i] = outbuf[i];
          outbuf[i] = b ^ *ivp++;
        }
      for (; i < blocksize; i++)
        outbuf[i] = 0 ^ *ivp++;

      nburn = enc_fn (&c->context.c, outbuf, outbuf);
      burn = nburn > burn ? nburn : burn;
      buf_cpy (c->u_iv.iv, outbuf, blocksize);
    }

  if (burn > 0)
    _gcry_burn_stack (burn + 4 * sizeof(void *));

  return 0;
}
Ejemplo n.º 15
0
gcry_err_code_t
_gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c,
                          unsigned char *outbuf, size_t outbuflen,
                          const unsigned char *inbuf, size_t inbuflen)
{
  size_t n;
  int i;
  size_t blocksize = c->spec->blocksize;
  gcry_cipher_decrypt_t dec_fn = c->spec->decrypt;
  size_t nblocks = inbuflen / blocksize;
  unsigned int burn, nburn;

  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
   * length, to allow better optimization of this function.  */
  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
    return GPG_ERR_INV_LENGTH;

  if (outbuflen < inbuflen)
    return GPG_ERR_BUFFER_TOO_SHORT;

  if ((inbuflen % blocksize)
      && !(inbuflen > blocksize
           && (c->flags & GCRY_CIPHER_CBC_CTS)))
    return GPG_ERR_INV_LENGTH;

  burn = 0;

  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
    {
      nblocks--;
      if ((inbuflen % blocksize) == 0)
	nblocks--;
      buf_cpy (c->lastiv, c->u_iv.iv, blocksize);
    }

  if (c->bulk.cbc_dec)
    {
      c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
      inbuf  += nblocks * blocksize;
      outbuf += nblocks * blocksize;
    }
  else
    {
      for (n=0; n < nblocks; n++ )
        {
          /* Because outbuf and inbuf might be the same, we must not overwrite
             the original ciphertext block.  We use LASTIV as intermediate
             storage here because it is not used otherwise.  */
          nburn = dec_fn ( &c->context.c, c->lastiv, inbuf );
          burn = nburn > burn ? nburn : burn;
          buf_xor_n_copy_2(outbuf, c->lastiv, c->u_iv.iv, inbuf, blocksize);
          inbuf  += blocksize;
          outbuf += blocksize;
        }
    }

  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
    {
      size_t restbytes;

      if ((inbuflen % blocksize) == 0)
        restbytes = blocksize;
      else
        restbytes = inbuflen % blocksize;

      buf_cpy (c->lastiv, c->u_iv.iv, blocksize );         /* Save Cn-2. */
      buf_cpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */

      nburn = dec_fn ( &c->context.c, outbuf, inbuf );
      burn = nburn > burn ? nburn : burn;
      buf_xor(outbuf, outbuf, c->u_iv.iv, restbytes);

      buf_cpy (outbuf + blocksize, outbuf, restbytes);
      for(i=restbytes; i < blocksize; i++)
        c->u_iv.iv[i] = outbuf[i];
      nburn = dec_fn (&c->context.c, outbuf, c->u_iv.iv);
      burn = nburn > burn ? nburn : burn;
      buf_xor(outbuf, outbuf, c->lastiv, blocksize);
      /* c->lastiv is now really lastlastiv, does this matter? */
    }

  if (burn > 0)
    _gcry_burn_stack (burn + 4 * sizeof(void *));

  return 0;
}
Ejemplo n.º 16
0
gcry_err_code_t
_gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c,
                          unsigned char *outbuf, size_t outbuflen,
                          const unsigned char *inbuf, size_t inbuflen)
{
  size_t n;
  int i;
  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
  unsigned int blocksize = c->spec->blocksize;
  size_t nblocks;
  unsigned int burn, nburn;

  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
   * length, to allow better optimization of this function.  */
  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
    return GPG_ERR_INV_LENGTH;

  if (outbuflen < inbuflen)
    return GPG_ERR_BUFFER_TOO_SHORT;

  burn = 0;

  /* First process a left over encrypted counter.  */
  if (c->unused)
    {
      gcry_assert (c->unused < blocksize);
      i = blocksize - c->unused;
      n = c->unused > inbuflen ? inbuflen : c->unused;
      buf_xor(outbuf, inbuf, &c->lastiv[i], n);
      c->unused -= n;
      inbuf  += n;
      outbuf += n;
      inbuflen -= n;
    }

  /* Use a bulk method if available.  */
  nblocks = inbuflen / blocksize;
  if (nblocks && c->bulk.ctr_enc)
    {
      c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
      inbuf  += nblocks * blocksize;
      outbuf += nblocks * blocksize;
      inbuflen -= nblocks * blocksize;
    }

  /* If we don't have a bulk method use the standard method.  We also
     use this method for the a remaining partial block.  */
  if (inbuflen)
    {
      unsigned char tmp[MAX_BLOCKSIZE];

      do {
        nburn = enc_fn (&c->context.c, tmp, c->u_ctr.ctr);
        burn = nburn > burn ? nburn : burn;

        for (i = blocksize; i > 0; i--)
          {
            c->u_ctr.ctr[i-1]++;
            if (c->u_ctr.ctr[i-1] != 0)
              break;
          }

        n = blocksize < inbuflen ? blocksize : inbuflen;
        buf_xor(outbuf, inbuf, tmp, n);

        inbuflen -= n;
        outbuf += n;
        inbuf += n;
      } while (inbuflen);

      /* Save the unused bytes of the counter.  */
      c->unused = blocksize - n;
      if (c->unused)
        buf_cpy (c->lastiv+n, tmp+n, c->unused);

      wipememory (tmp, sizeof tmp);
    }

  if (burn > 0)
    _gcry_burn_stack (burn + 4 * sizeof(void *));

  return 0;
}