Exemple #1
0
/*

=item C<static int
get_signature_length(expression * const e)>

Calculate the length of the signature for one operand; an operand is separated
from the instruction name or another operand through '_', which must also
be counted.

 set $I0, 42  --> set_i_ic

therefore, for $I0 (a target), return 1 for the type, 1 for the '_', and whatever
is needed for a key, if any, as in this example:

 set $P0[1] = "hi"  --> set_p_kic_sc

$P0 is a target, resulting in "_p", the key [1] is a key ('k') of type int ('i'),
and it's a constant ('c'). Add 1 for the '_'.

=cut

*/
PARROT_WARN_UNUSED_RESULT
static int
get_signature_length(NOTNULL(expression * const e)) {
    switch (e->type) {
        case EXPR_TARGET:
            return 2 + ((e->expr.t->key != NULL) /* if there's a key on this target ... */
                                                 /* ... get its length. */
                       ? get_signature_length(e->expr.t->key->head->expr) + 1
                       : 0);
        case EXPR_CONSTANT:
            return 3;    /* for _, 'k', 'c' */
        case EXPR_IDENT:
            return 3; /* 1 for '_', 1 for 'i', 1 for 'c' */
        case EXPR_KEY: { /* for '_', 'k' */
            int n;
            /* if the key is an integer constant, then signature becomes '_kic', otherwise _kc. */
            if (e->expr.k->head->expr->type         == EXPR_CONSTANT
            &&  e->expr.k->head->expr->expr.c->type == INT_VAL)
                n = 3;
            else
                n = 2;

            return n + get_signature_length(e->expr.k->head->expr);
        }
        default:
            fprintf(stderr, "wrong expression typein get_signature_length()\n");
            break;
    }
    return 0;
}
Exemple #2
0
static int16_t u2f_register(struct u2f_register_request * req)
{
    uint8_t i[] = {0x0,U2F_EC_FMT_UNCOMPRESSED};

    uint8_t key_handle[U2F_KEY_HANDLE_SIZE];
    uint8_t pubkey[64];


    const uint16_t attest_size = u2f_attestation_cert_size();

    if (u2f_get_user_feedback())
    {
        return U2F_SW_CONDITIONS_NOT_SATISFIED;
    }

    if ( u2f_new_keypair(key_handle, pubkey) == -1)
    {
    	return U2F_SW_CONDITIONS_NOT_SATISFIED;
    }

    u2f_sha256_start();
    u2f_sha256_update(i,1);
    u2f_sha256_update(req->app,32);

    u2f_sha256_update(req->chal,32);

    u2f_sha256_update(key_handle,U2F_KEY_HANDLE_SIZE);
    u2f_sha256_update(i+1,1);
    u2f_sha256_update(pubkey,64);
    u2f_sha256_finish();
    
    if (u2f_ecdsa_sign((uint8_t*)req, U2F_ATTESTATION_HANDLE) == -1)
	{
    	return U2F_SW_WRONG_DATA;
	}

    u2f_hid_set_len(69 + get_signature_length((uint8_t*)req) + U2F_KEY_HANDLE_SIZE + u2f_attestation_cert_size());
    i[0] = 0x5;
    u2f_response_writeback(i,2);
    u2f_response_writeback(pubkey,64);
    i[0] = U2F_KEY_HANDLE_SIZE;
    u2f_response_writeback(i,1);
    u2f_response_writeback(key_handle,U2F_KEY_HANDLE_SIZE);

    u2f_response_writeback_progmem(u2f_get_attestation_cert(),u2f_attestation_cert_size());

    dump_signature_der((uint8_t*)req);


    return U2F_SW_NO_ERROR;
}
Exemple #3
0
/*

=item C<static char *
get_signatured_opname(instruction * const instr)>

Returns the full opname of the instruction C<name>; the signature
of the opname is based on the operands, some examples are shown
below:

 set I0, 10        --> set_i_ic
 print "hi"        --> print_sc
 set P0[1], 3.14   --> set_p_kic_nc

For each operand, an underscore is added; then for the types
int, num, string or pmc, an 'i', 'n', 's' or 'p' is added
respectively. If the operand is a constant, a 'c' suffic is added.

If the operand is a key of something, a 'k' prefix is added.

=cut

*/
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
static char *
get_signatured_opname(NOTNULL(lexer_state * const lexer), NOTNULL(instruction * const instr)) {
    size_t      fullname_length;
    char       *fullname;
    char       *instr_writer;
    expression *iter         = instr->operands;
    unsigned    num_operands = 0;

    /* get length of short opname (and add 1 for the NULL character) */
    fullname_length = strlen(instr->opname) + 1;

    /* for each operand, calculate the length of the signature (for that op.)
     * and add it to the full length.
     */
    if (iter) {
        iter = iter->next;
        do {
            int keylength    = get_signature_length(iter);
            fullname_length += keylength;
            iter             = iter->next;
            ++num_operands;
        }
        while (iter != instr->operands->next);
    }

    /* now we know how long the fullname will be, allocate enough memory. */
    fullname = (char *)pir_mem_allocate_zeroed(lexer, fullname_length * sizeof (char));

    /* copy the short name into fullname buffer, and set instr_writer to
     * the character after that.
     */
    strcpy(fullname, instr->opname);
    instr_writer = fullname + strlen(instr->opname);

    /* now iterate again over all operands, and codify them into the fullname.
     * As we counted the number of operands, this loop can be written a bit simpler.
     */
    iter = instr->operands;
    while (num_operands-- > 0) {
        iter            = iter->next;
        *instr_writer++ = '_'; /* separate each operand code by a '_' */
        instr_writer    = write_signature(iter, instr_writer);
    }

    return fullname;
}
Exemple #4
0
static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control)
{

	uint8_t up = 1;
	uint32_t count;
	if (u2f_load_key(req->kh) != 0)
	{
		u2f_hid_set_len(2);
		return U2F_SW_WRONG_DATA;
	}
	else if (control == U2F_AUTHENTICATE_CHECK)
	{
		u2f_hid_set_len(2);
		return U2F_SW_CONDITIONS_NOT_SATISFIED;
	}

	if (u2f_get_user_feedback())
	{
		u2f_hid_set_len(2);
		return U2F_SW_CONDITIONS_NOT_SATISFIED;
	}

	count = u2f_count();

    u2f_sha256_start();
    u2f_sha256_update(req->app,32);
    u2f_sha256_update(&up,1);
    u2f_sha256_update((uint8_t *)&count,4);
    u2f_sha256_update(req->chal,32);

    u2f_sha256_finish();

    if (u2f_ecdsa_sign((uint8_t*)req, req->kh) == -1)
	{
    	return U2F_SW_WRONG_DATA;
	}

    u2f_hid_set_len(7 + get_signature_length((uint8_t*)req));

    u2f_response_writeback(&up,1);
    u2f_response_writeback((uint8_t *)&count,4);
    dump_signature_der((uint8_t*)req);

	return U2F_SW_NO_ERROR;
}