示例#1
0
文件: UNPAIRS.CPP 项目: ems/TMS
void MatchGraph::UNPAIR (long oldbase, long oldmate)

{   long e, newbase, u;

#ifdef DEBUG
    printf("Unpair oldbase, oldmate=%d %d\n",oldbase, oldmate);
#endif

    UNLINK (oldbase);
    newbase = BMATE (oldmate);
    if (newbase != oldbase) {
	LINK [(int)oldbase] = -DUMMYEDGE;
	REMATCH (newbase, MATE[(int)oldbase]);
	if (f == LASTEDGE[1])
	    LINK[(int)secondmate] = -LASTEDGE[2];
	else LINK[(int)secondmate] = -LASTEDGE[1];
	}
    e = LINK[(int)oldmate];
    u = BEND (OPPEDGE (e));
    if (u == newbase) {
	POINTER (newbase, oldmate, e);
	return;
	}
    LINK[BMATE (u)] = -e;
    do {
	e = -LINK[(int)u];
	v = BMATE (u);
	POINTER (u, v, -LINK[(int)v]);
	u = BEND (e);
    } while (u != newbase);
    e = OPPEDGE (e);
    POINTER (newbase, oldmate, e);
}
示例#2
0
static bool
tls_crypt_v2_wrap_client_key(struct buffer *wkc,
                             const struct key2 *src_key,
                             const struct buffer *src_metadata,
                             struct key_ctx *server_key, struct gc_arena *gc)
{
    cipher_ctx_t *cipher_ctx = server_key->cipher;
    struct buffer work = alloc_buf_gc(TLS_CRYPT_V2_MAX_WKC_LEN
                                      + cipher_ctx_block_size(cipher_ctx), gc);

    /* Calculate auth tag and synthetic IV */
    uint8_t *tag = buf_write_alloc(&work, TLS_CRYPT_TAG_SIZE);
    if (!tag)
    {
        msg(M_WARN, "ERROR: could not write tag");
        return false;
    }
    uint16_t net_len = htons(sizeof(src_key->keys) + BLEN(src_metadata)
                             + TLS_CRYPT_V2_TAG_SIZE + sizeof(uint16_t));
    hmac_ctx_t *hmac_ctx = server_key->hmac;
    hmac_ctx_reset(hmac_ctx);
    hmac_ctx_update(hmac_ctx, (void *)&net_len, sizeof(net_len));
    hmac_ctx_update(hmac_ctx, (void *)src_key->keys, sizeof(src_key->keys));
    hmac_ctx_update(hmac_ctx, BPTR(src_metadata), BLEN(src_metadata));
    hmac_ctx_final(hmac_ctx, tag);

    dmsg(D_CRYPTO_DEBUG, "TLS-CRYPT WRAP TAG: %s",
         format_hex(tag, TLS_CRYPT_TAG_SIZE, 0, gc));

    /* Use the 128 most significant bits of the tag as IV */
    ASSERT(cipher_ctx_reset(cipher_ctx, tag));

    /* Overflow check (OpenSSL requires an extra block in the dst buffer) */
    if (buf_forward_capacity(&work) < (sizeof(src_key->keys)
                                       + BLEN(src_metadata)
                                       + sizeof(net_len)
                                       + cipher_ctx_block_size(cipher_ctx)))
    {
        msg(M_WARN, "ERROR: could not crypt: insufficient space in dst");
        return false;
    }

    /* Encrypt */
    int outlen = 0;
    ASSERT(cipher_ctx_update(cipher_ctx, BEND(&work), &outlen,
                             (void *)src_key->keys, sizeof(src_key->keys)));
    ASSERT(buf_inc_len(&work, outlen));
    ASSERT(cipher_ctx_update(cipher_ctx, BEND(&work), &outlen,
                             BPTR(src_metadata), BLEN(src_metadata)));
    ASSERT(buf_inc_len(&work, outlen));
    ASSERT(cipher_ctx_final(cipher_ctx, BEND(&work), &outlen));
    ASSERT(buf_inc_len(&work, outlen));
    ASSERT(buf_write(&work, &net_len, sizeof(net_len)));

    return buf_copy(wkc, &work);
}
示例#3
0
static void
stub_decompress(struct buffer *buf, struct buffer work,
                struct compress_context *compctx,
                const struct frame *frame)
{
    uint8_t c;
    if (buf->len <= 0)
    {
        return;
    }
    if (compctx->flags & COMP_F_SWAP)
    {
        uint8_t *head = BPTR(buf);
        c = *head;
        --buf->len;
        *head = *BEND(buf);
        if (c != NO_COMPRESS_BYTE_SWAP)
        {
            dmsg(D_COMP_ERRORS, "Bad compression stub (swap) decompression header byte: %d", c);
            buf->len = 0;
        }
    }
    else
    {
        c = *BPTR(buf);
        ASSERT(buf_advance(buf, 1));
        if (c != NO_COMPRESS_BYTE)
        {
            dmsg(D_COMP_ERRORS, "Bad compression stub decompression header byte: %d", c);
            buf->len = 0;
        }
    }
}
示例#4
0
static void
stub_compress(struct buffer *buf, struct buffer work,
              struct compress_context *compctx,
              const struct frame *frame)
{
    if (buf->len <= 0)
    {
        return;
    }
    if (compctx->flags & COMP_F_SWAP)
    {
        uint8_t *head = BPTR(buf);
        uint8_t *tail  = BEND(buf);
        ASSERT(buf_safe(buf, 1));
        ++buf->len;

        /* move head byte of payload to tail */
        *tail = *head;
        *head = NO_COMPRESS_BYTE_SWAP;
    }
    else
    {
        uint8_t *header = buf_prepend(buf, 1);
        *header = NO_COMPRESS_BYTE;
    }
}
示例#5
0
文件: TERM.CPP 项目: ems/TMS
void MatchGraph::UNPAIR_ALL ()
{
    long u;

    for (v=1; v <= U; ++v) {
	if (BASE[(int)v] != v || LASTVTX[(int)v] == v)
	    continue;
	nextu = v;
	NEXTVTX[(int)LASTVTX[(int)nextu]] = DUMMYVERTEX;
	while (1) {
	    u = nextu;
	    nextu = NEXTVTX[(int)nextu];
	    UNLINK (u);
	    if (LASTVTX[(int)u] != u) {
		f = (LASTEDGE[2] == OPPEDGE(e)) ? LASTEDGE[1] : LASTEDGE[2];
		NEXTVTX[(int)LASTVTX[(int)BEND(f)]] = u;
	    }
	    newbase = BMATE (BMATE(u));
	    if (newbase != DUMMYVERTEX && newbase != u) {
		LINK[(int)u] = -DUMMYEDGE;
		REMATCH (newbase, MATE[(int)u]);
	    }
	    while (LASTVTX[(int)nextu] == nextu && nextu != DUMMYVERTEX)
		nextu = NEXTVTX[(int)nextu];
	    if (LASTVTX[(int)nextu] == nextu && nextu == DUMMYVERTEX)
		break;
	}
    }
}
示例#6
0
文件: TERM.CPP 项目: ems/TMS
void MatchGraph::SET_MATCH_BOUNDS ()
{
    long del;

    for (v=1; v <= U; ++v) {
	if (LINK[(int)v] < 0 || BASE[(int)v] != v) {
	    NEXT_D[(int)v] = LAST_D;
	    continue;
	}
	LINK[(int)v] = -LINK[(int)v];
	i = v;
	while (i != DUMMYVERTEX) {
	    Y[(int)i] -= DELTA;
	    i = NEXTVTX[(int)i];
	}
	f = MATE[(int)v];
	if (f != DUMMYEDGE) {
	    i = BEND(f);
	    del = SLACK(f);
	    while (i != DUMMYVERTEX) {
		Y[(int)i] -= del;
		i = NEXTVTX[(int)i];
	    }
	}
	NEXT_D[(int)v] = LAST_D;
    }
}
示例#7
0
文件: UNPAIRS.CPP 项目: ems/TMS
void MatchGraph::REMATCH (long firstmate, long e)
{
#ifdef DEBUG
     printf("Rematch firstmate=%d e=%d-%d\n",firstmate, END[OPPEDGE(e)], END[e]);
#endif

    MATE[(int)firstmate] = e;
    nexte = -LINK[(int)firstmate];
    while (nexte != DUMMYEDGE) {
	e = nexte;
	f = OPPEDGE (e);
	firstmate = BEND (e);
	secondmate = BEND (f);
	nexte = -LINK[(int)firstmate];
	LINK[(int)firstmate] = -MATE[(int)secondmate];
	LINK[(int)secondmate] = -MATE[(int)firstmate];
	MATE[(int)firstmate] = f;
	MATE[(int)secondmate] = e;
	}
}
示例#8
0
/* updateWts:
 * Iterate over edges in a cell, adjust weights as necessary.
 * It always updates the bent edges belonging to a cell.
 * A horizontal/vertical edge is updated only if the edge traversed
 * is bent, or if it is the traversed edge.
 */
void
updateWts (sgraph* g, cell* cp, sedge* ep)
{
    int i;
    sedge* e;
    int isBend = BEND(g,ep);
    int hsz = CHANSZ (cp->bb.UR.y - cp->bb.LL.y);
    int vsz = CHANSZ (cp->bb.UR.x - cp->bb.LL.x);
    int minsz = MIN(hsz, vsz);

    /* Bend edges are added first */
    for (i = 0; i < cp->nedges; i++) {
	e = cp->edges[i];
	if (!BEND(g,e)) break;
	updateWt (cp, e, minsz);
}

    for (; i < cp->nedges; i++) {
	e = cp->edges[i];
	if (isBend || (e == ep)) updateWt (cp, e, (HORZ(g,e)?hsz:vsz));
    }
}
示例#9
0
bool
buf_puts(struct buffer *buf, const char *str)
{
  int ret = false;
  uint8_t *ptr = BEND (buf);
  int cap = buf_forward_capacity (buf);
  if (cap > 0)
    {
      strncpynt ((char *)ptr,str, cap);
      *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
      buf->len += (int) strlen ((char *)ptr);
      ret = true;
    }
  return ret;
}
示例#10
0
文件: buffer.c 项目: angelol/iOpenVPN
/*
 * printf append to a buffer with overflow check
 */
void
buf_printf (struct buffer *buf, const char *format, ...)
{
  if (buf_defined (buf))
    {
      va_list arglist;
      uint8_t *ptr = BEND (buf);
      int cap = buf_forward_capacity (buf);

      if (cap > 0)
	{
	  va_start (arglist, format);
	  vsnprintf ((char *)ptr, cap, format, arglist);
	  va_end (arglist);
	  *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
	  buf->len += (int) strlen ((char *)ptr);
	}
    }
}
示例#11
0
static void
lz4_compress(struct buffer *buf, struct buffer work,
             struct compress_context *compctx,
             const struct frame *frame)
{
    bool compressed;
    if (buf->len <= 0)
    {
        return;
    }

    compressed = do_lz4_compress(buf, &work, compctx, frame);

    /* On error do_lz4_compress sets buf len to zero, just return */
    if (buf->len == 0)
    {
        return;
    }

    /* did compression save us anything? */
    {
        uint8_t comp_head_byte = NO_COMPRESS_BYTE_SWAP;
        if (compressed && work.len < buf->len)
        {
            *buf = work;
            comp_head_byte = LZ4_COMPRESS_BYTE;
        }

        {
            uint8_t *head = BPTR(buf);
            uint8_t *tail  = BEND(buf);
            ASSERT(buf_safe(buf, 1));
            ++buf->len;

            /* move head byte of payload to tail */
            *tail = *head;
            *head = comp_head_byte;
        }
    }
}
示例#12
0
/*
 * printf append to a buffer with overflow check
 */
bool
buf_printf (struct buffer *buf, const char *format, ...)
{
  int ret = false;
  if (buf_defined (buf))
    {
      va_list arglist;
      uint8_t *ptr = BEND (buf);
      int cap = buf_forward_capacity (buf);

      if (cap > 0)
	{
	  int stat;
	  va_start (arglist, format);
	  stat = vsnprintf ((char *)ptr, cap, format, arglist);
	  va_end (arglist);
	  *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
	  buf->len += (int) strlen ((char *)ptr);
	  if (stat >= 0 && stat < cap)
	    ret = true;
	}
    }
  return ret;
}
示例#13
0
static void
lz4_decompress(struct buffer *buf, struct buffer work,
               struct compress_context *compctx,
               const struct frame *frame)
{
    size_t zlen_max = EXPANDED_SIZE(frame);
    uint8_t c;          /* flag indicating whether or not our peer compressed */

    if (buf->len <= 0)
    {
        return;
    }

    ASSERT(buf_init(&work, FRAME_HEADROOM(frame)));

    /* do unframing/swap (assumes buf->len > 0) */
    {
        uint8_t *head = BPTR(buf);
        c = *head;
        --buf->len;
        *head = *BEND(buf);
    }

    if (c == LZ4_COMPRESS_BYTE) /* packet was compressed */
    {
        do_lz4_decompress(zlen_max, &work, buf, compctx);
    }
    else if (c == NO_COMPRESS_BYTE_SWAP) /* packet was not compressed */
    {
    }
    else
    {
        dmsg(D_COMP_ERRORS, "Bad LZ4 decompression header byte: %d", c);
        buf->len = 0;
    }
}
示例#14
0
bool
tls_crypt_v2_extract_client_key(struct buffer *buf,
                                struct tls_wrap_ctx *ctx,
                                const struct tls_options *opt)
{
    if (!ctx->tls_crypt_v2_server_key.cipher)
    {
        msg(D_TLS_ERRORS,
            "Client wants tls-crypt-v2, but no server key present.");
        return false;
    }

    msg(D_HANDSHAKE, "Control Channel: using tls-crypt-v2 key");

    struct buffer wrapped_client_key = *buf;
    uint16_t net_len = 0;

    if (BLEN(&wrapped_client_key) < sizeof(net_len))
    {
        msg(D_TLS_ERRORS, "failed to read length");
    }
    memcpy(&net_len, BEND(&wrapped_client_key) - sizeof(net_len),
           sizeof(net_len));

    size_t wkc_len = ntohs(net_len);
    if (!buf_advance(&wrapped_client_key, BLEN(&wrapped_client_key) - wkc_len))
    {
        msg(D_TLS_ERRORS, "Can not locate tls-crypt-v2 client key");
        return false;
    }

    struct key2 client_key = { 0 };
    ctx->tls_crypt_v2_metadata = alloc_buf(TLS_CRYPT_V2_MAX_METADATA_LEN);
    if (!tls_crypt_v2_unwrap_client_key(&client_key,
                                        &ctx->tls_crypt_v2_metadata,
                                        wrapped_client_key,
                                        &ctx->tls_crypt_v2_server_key))
    {
        msg(D_TLS_ERRORS, "Can not unwrap tls-crypt-v2 client key");
        secure_memzero(&client_key, sizeof(client_key));
        return false;
    }

    /* Load the decrypted key */
    ctx->mode = TLS_WRAP_CRYPT;
    ctx->cleanup_key_ctx = true;
    ctx->opt.flags |= CO_PACKET_ID_LONG_FORM;
    memset(&ctx->opt.key_ctx_bi, 0, sizeof(ctx->opt.key_ctx_bi));
    tls_crypt_v2_load_client_key(&ctx->opt.key_ctx_bi, &client_key, true);
    secure_memzero(&client_key, sizeof(client_key));

    /* Remove client key from buffer so tls-crypt code can unwrap message */
    ASSERT(buf_inc_len(buf, -(BLEN(&wrapped_client_key))));

    if (opt && opt->tls_crypt_v2_verify_script)
    {
        return tls_crypt_v2_verify_metadata(ctx, opt);
    }

    return true;
}
示例#15
0
static bool
tls_crypt_v2_unwrap_client_key(struct key2 *client_key, struct buffer *metadata,
                               struct buffer wrapped_client_key,
                               struct key_ctx *server_key)
{
    const char *error_prefix = __func__;
    bool ret = false;
    struct gc_arena gc = gc_new();
    /* The crypto API requires one extra cipher block of buffer head room when
     * decrypting, which nicely matches the tag size of WKc.  So
     * TLS_CRYPT_V2_MAX_WKC_LEN is always large enough for the plaintext. */
    uint8_t plaintext_buf_data[TLS_CRYPT_V2_MAX_WKC_LEN] = { 0 };
    struct buffer plaintext = { 0 };

    dmsg(D_TLS_DEBUG_MED, "%s: unwrapping client key (len=%d): %s", __func__,
         BLEN(&wrapped_client_key), format_hex(BPTR(&wrapped_client_key),
                                               BLEN(&wrapped_client_key),
                                               0, &gc));

    if (TLS_CRYPT_V2_MAX_WKC_LEN < BLEN(&wrapped_client_key))
    {
        CRYPT_ERROR("wrapped client key too big");
    }

    /* Decrypt client key and metadata */
    uint16_t net_len = 0;
    const uint8_t *tag = BPTR(&wrapped_client_key);

    if (BLEN(&wrapped_client_key) < sizeof(net_len))
    {
        CRYPT_ERROR("failed to read length");
    }
    memcpy(&net_len, BEND(&wrapped_client_key) - sizeof(net_len),
           sizeof(net_len));

    if (ntohs(net_len) != BLEN(&wrapped_client_key))
    {
        dmsg(D_TLS_DEBUG_LOW, "%s: net_len=%u, BLEN=%i", __func__,
             ntohs(net_len), BLEN(&wrapped_client_key));
        CRYPT_ERROR("invalid length");
    }

    buf_inc_len(&wrapped_client_key, -(int)sizeof(net_len));

    if (!buf_advance(&wrapped_client_key, TLS_CRYPT_TAG_SIZE))
    {
        CRYPT_ERROR("failed to read tag");
    }

    if (!cipher_ctx_reset(server_key->cipher, tag))
    {
        CRYPT_ERROR("failed to initialize IV");
    }
    buf_set_write(&plaintext, plaintext_buf_data, sizeof(plaintext_buf_data));
    int outlen = 0;
    if (!cipher_ctx_update(server_key->cipher, BPTR(&plaintext), &outlen,
                           BPTR(&wrapped_client_key),
                           BLEN(&wrapped_client_key)))
    {
        CRYPT_ERROR("could not decrypt client key");
    }
    ASSERT(buf_inc_len(&plaintext, outlen));

    if (!cipher_ctx_final(server_key->cipher, BEND(&plaintext), &outlen))
    {
        CRYPT_ERROR("cipher final failed");
    }
    ASSERT(buf_inc_len(&plaintext, outlen));

    /* Check authentication */
    uint8_t tag_check[TLS_CRYPT_TAG_SIZE] = { 0 };
    hmac_ctx_reset(server_key->hmac);
    hmac_ctx_update(server_key->hmac, (void *)&net_len, sizeof(net_len));
    hmac_ctx_update(server_key->hmac, BPTR(&plaintext),
                    BLEN(&plaintext));
    hmac_ctx_final(server_key->hmac, tag_check);

    if (memcmp_constant_time(tag, tag_check, sizeof(tag_check)))
    {
        dmsg(D_CRYPTO_DEBUG, "tag      : %s",
             format_hex(tag, sizeof(tag_check), 0, &gc));
        dmsg(D_CRYPTO_DEBUG, "tag_check: %s",
             format_hex(tag_check, sizeof(tag_check), 0, &gc));
        CRYPT_ERROR("client key authentication error");
    }

    if (buf_len(&plaintext) < sizeof(client_key->keys))
    {
        CRYPT_ERROR("failed to read client key");
    }
    memcpy(&client_key->keys, BPTR(&plaintext), sizeof(client_key->keys));
    ASSERT(buf_advance(&plaintext, sizeof(client_key->keys)));

    if (!buf_copy(metadata, &plaintext))
    {
        CRYPT_ERROR("metadata too large for supplied buffer");
    }

    ret = true;
error_exit:
    if (!ret)
    {
        secure_memzero(client_key, sizeof(*client_key));
    }
    buf_clear(&plaintext);
    gc_free(&gc);
    return ret;
}
示例#16
0
bool
tls_crypt_wrap(const struct buffer *src, struct buffer *dst,
               struct crypto_options *opt)
{
    const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
    struct gc_arena gc;

    /* IV, packet-ID and implicit IV required for this mode. */
    ASSERT(ctx->cipher);
    ASSERT(ctx->hmac);
    ASSERT(packet_id_initialized(&opt->packet_id));
    ASSERT(hmac_ctx_size(ctx->hmac) == 256/8);

    gc_init(&gc);

    dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP FROM: %s",
         format_hex(BPTR(src), BLEN(src), 80, &gc));

    /* Get packet ID */
    if (!packet_id_write(&opt->packet_id.send, dst, true, false))
    {
        msg(D_CRYPT_ERRORS, "TLS-CRYPT ERROR: packet ID roll over.");
        goto err;
    }

    dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s",
         format_hex(BPTR(dst), BLEN(dst), 0, &gc));

    /* Buffer overflow check */
    if (!buf_safe(dst, BLEN(src) + TLS_CRYPT_BLOCK_SIZE + TLS_CRYPT_TAG_SIZE))
    {
        msg(D_CRYPT_ERRORS, "TLS-CRYPT WRAP: buffer size error, "
            "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->capacity, src->offset,
            src->len, dst->capacity, dst->offset, dst->len);
        goto err;
    }

    /* Calculate auth tag and synthetic IV */
    {
        uint8_t *tag = NULL;
        hmac_ctx_reset(ctx->hmac);
        hmac_ctx_update(ctx->hmac, BPTR(dst), BLEN(dst));
        hmac_ctx_update(ctx->hmac, BPTR(src), BLEN(src));

        ASSERT(tag = buf_write_alloc(dst, TLS_CRYPT_TAG_SIZE));
        hmac_ctx_final(ctx->hmac, tag);

        dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP TAG: %s",
             format_hex(tag, TLS_CRYPT_TAG_SIZE, 0, &gc));

        /* Use the 128 most significant bits of the tag as IV */
        ASSERT(cipher_ctx_reset(ctx->cipher, tag));
    }

    /* Encrypt src */
    {
        int outlen = 0;
        ASSERT(cipher_ctx_update(ctx->cipher, BEND(dst), &outlen,
                                 BPTR(src), BLEN(src)));
        ASSERT(buf_inc_len(dst, outlen));
        ASSERT(cipher_ctx_final(ctx->cipher, BPTR(dst), &outlen));
        ASSERT(buf_inc_len(dst, outlen));
    }

    dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP TO: %s",
         format_hex(BPTR(dst), BLEN(dst), 80, &gc));

    gc_free(&gc);
    return true;

err:
    crypto_clear_error();
    dst->len = 0;
    gc_free(&gc);
    return false;
}