Пример #1
0
int bytestring_erase(bytestring_t *bs,
                     unsigned pos,
                     unsigned len)
{
  if (pos>=bs->len)
    return BYTESTRING_OK;
  if (pos+len>=bs->len) 
    return bytestring_resize(bs,pos);
  memmove(bs->data+pos,bs->data+pos+len,bs->len-pos-len);
  bytestring_resize(bs,bs->len-len);
  return BYTESTRING_OK;
}
Пример #2
0
int bytestring_assign_uchar(bytestring_t* bs,
                         unsigned len, unsigned char c)
{
  bytestring_resize(bs,len);
  memset(bs->data,c,len);
  return BYTESTRING_OK;
}
Пример #3
0
int bytestring_assign_data(bytestring_t* bs,
                        unsigned len, const unsigned char *data)
{
  bytestring_resize(bs,len);
  memcpy(bs->data,data,len);
  return BYTESTRING_OK;
}
Пример #4
0
// Append printf()-style string data to the end of a bytestring.
bytestring *bytestring_append_printf(bytestring *bs, const char *fmt, ...)
{
  va_list args;

  while (1)
  {
    int count;
    int slack = bs->size - bs->length;

    // Attempt the printf() with whatever slack space we have left
    va_start(args, fmt);
    count = vsnprintf((char *) bs->data + bs->length, slack, fmt, args);
    va_end(args);

    // Unexpected failure
    if (count < 0)
      abort();

    // If there was enough space, we're all done
    if (count < slack)
    {
      bs->length += count;
      return bs;
    }

    // Add the required amount of slack space
    bytestring_resize(bs, bs->length + count + 1);  // +1 because we need space for NUL byte not included in count
  }
}
Пример #5
0
int bytestring_insert_uchar(bytestring_t *bs,
                            unsigned pos,
                            unsigned len, unsigned char c)
{
  if (pos>=bs->len)
    return bytestring_append_uchar(bs,len,c);
  bytestring_resize(bs,bs->len+len);
  memmove(bs->data+pos+len,bs->data+pos,len);
  memset(bs->data,c,len);
  return BYTESTRING_OK;
}
Пример #6
0
int bytestring_insert_data(bytestring_t *bs,
                           unsigned pos,
                           unsigned len, const unsigned char* data)
{
  if (pos>=bs->len)
    return bytestring_append_data(bs,len,data);
  bytestring_resize(bs,bs->len+len);
  memmove(bs->data+pos+len,bs->data+pos,len);
  memcpy(bs->data,data,len);
  return BYTESTRING_OK;
}
Пример #7
0
// Append a single byte to the end of the bytestring.
bytestring *bytestring_append_byte(bytestring *bs, uint8_t byte)
{
  // Ensure enough space to hold all data
  if (bs->size < (bs->length + 1))
    bytestring_resize(bs, (bs->length + 1));

  // Append the data to the end
  bs->data[bs->length] = byte;
  bs->length++;

  return bs;
}
Пример #8
0
// Append the given bytes to the end of the bytestring.
bytestring *bytestring_append_bytes(bytestring *bs, const uint8_t *data, size_t length)
{
  // Ensure enough space to hold all data
  if (bs->size < (bs->length + length))
    bytestring_resize(bs, (bs->length + length));

  // Append the data to the end
  memcpy(bs->data + bs->length, data, length);
  bs->length += length;

  return bs;
}
Пример #9
0
// Replace the contents of the bytestring with the given bytes.
bytestring *bytestring_set_bytes(bytestring *bs, const uint8_t *data, size_t length)
{
  // Ensure enough space to hold all data
  if (bs->size < length)
    bytestring_resize(bs, length);

  // Copy the data
  memcpy(bs->data, data, length);
  bs->length = length;

  return bs;
}
Пример #10
0
crypto_error_t crypto_digest(bytestring_t *dst,
                             const bytestring_t *ctx,
                             const bytestring_t *src)
{
    unsigned char alg;

    bytestring_get_element(&alg,ctx,0);

    if (alg==CRYPTO_ALG_SHA1)
    {
        bytestring_resize(dst,SHA_DIGEST_LENGTH);
        SHA1(src->data,bytestring_get_size(src),dst->data);
    }
    else
        return CRYPTO_ERROR_UNKNOWN_ALGORITHM;
    return CRYPTO_OK;
}
Пример #11
0
// Append data to one bytestring from another, using the given source position and length.
bytestring *bytestring_append_bytestring(bytestring *bs, const bytestring *src, int position, size_t length)
{
  // Start position bounds check
  if ((position < 0) || (position >= src->length))
    return bs;  // Nothing to do

  // Length bounds check
  if (position + length > src->length)
    length = src->length - position;

  // Ensure enough space to hold all data
  if (bs->size < (bs->length + length))
    bytestring_resize(bs, (bs->length + length));

  // Append the data to the end
  memcpy(bs->data + bs->length, src->data + position, length);
  bs->length += length;

  return bs;
}
Пример #12
0
// As above, but don't use varargs.
bytestring *bytestring_append_vprintf(bytestring *bs, const char *fmt, va_list args)
{
  int count;
  int slack = bs->size - bs->length;

  // Make a copy of the original args, in case we need to retry
  va_list original_args;
  va_copy(original_args, args);

  // Attempt the printf() with whatever slack space we have left
  count = vsnprintf((char *) bs->data + bs->length, slack, fmt, args);

  // Unexpected failure
  if (count < 0)
    abort();

  // If there was enough space, we're all done
  if (count < slack)
  {
    va_end(original_args);
    bs->length += count;
    return bs;
  }

  // Add the required amount of slack space
  bytestring_resize(bs, bs->length + count + 1);  // +1 because we need space for NUL byte not included in count
  slack = bs->size - bs->length;

  // Retry the printf()
  count = vsnprintf((char *) bs->data + bs->length, slack, fmt, original_args);
  va_end(original_args);

  // This should not happen, since we allocated enough space
  if ((count < 0) || (count >= slack))
    abort();

  // Fix up length
  bs->length += count;

  return bs;
}
Пример #13
0
static crypto_error_t crypto_cipher(bytestring_t *dst,
                                    const bytestring_t *ctx,
                                    const bytestring_t *src,
                                    const bytestring_t *iv,
                                    int enc)
{
    unsigned u;
    unsigned char alg;
    DES_key_schedule key_schedule;
    DES_key_schedule key_schedule2;

    if (bytestring_get_element(&alg,ctx,0)!=BYTESTRING_OK)
        return CRYPTO_ERROR_UNKNOWN;

    if ((bytestring_get_size(src)&0x7)!=0)
        return CRYPTO_ERROR_BAD_CLEARTEXT_LENGTH;

    switch (alg)
    {
        case CRYPTO_ALG_DES_ECB:
            bytestring_resize(dst,bytestring_get_size(src));

            memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE);

            for (u=0; u<bytestring_get_size(src)/8; u++)
                DES_ecb_encrypt((const_DES_cblock *)(src->data+u*8),
                                (DES_cblock *)(dst->data+u*8),
                                &key_schedule,
                                enc);
            break;
        case CRYPTO_ALG_DES_CBC:
            if (iv==NULL || bytestring_get_size(iv)!=8)
                return CRYPTO_ERROR_BAD_IV_LENGTH;

            bytestring_resize(dst,bytestring_get_size(src));

            memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE);
            
            DES_ncbc_encrypt(src->data,
                             dst->data,
                             bytestring_get_size(src),
                             &key_schedule,
                             (DES_cblock *)(iv->data),
                             enc);
            break;
        case CRYPTO_ALG_DES2_EDE_ECB:
            bytestring_resize(dst,bytestring_get_size(src));

            memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE);
            memcpy(&key_schedule2,ctx->data+KS_HEADER_SIZE+DES_KS_SIZE,DES_KS_SIZE);
            
            for (u=0; u<bytestring_get_size(src)/8; u++)
                DES_ecb2_encrypt((const_DES_cblock *)(src->data+u*8),
                                 (DES_cblock *)(dst->data+u*8),
                                 &key_schedule,
                                 &key_schedule2,
                                 enc);
            break;
        case CRYPTO_ALG_DES2_EDE_CBC:
            if (iv==NULL || bytestring_get_size(iv)!=8)
                return CRYPTO_ERROR_BAD_IV_LENGTH;

            bytestring_resize(dst,bytestring_get_size(src));


            memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE);
            memcpy(&key_schedule2,ctx->data+KS_HEADER_SIZE+DES_KS_SIZE,DES_KS_SIZE);

            DES_ede2_cbc_encrypt(src->data,
                                 dst->data,
                                 bytestring_get_size(src),
                                 &key_schedule,
                                 &key_schedule2,
                                 (DES_cblock *)(iv->data),
                                 enc);
            break;
        default:
            return CRYPTO_ERROR_UNKNOWN_ALGORITHM;
    }
    return CRYPTO_OK;
}