Exemplo n.º 1
0
int jhae_decryption_verification(unsigned char *msg, unsigned long long *msglen,
                                 const unsigned char *key,
                                 const unsigned char *noc,
                                 const unsigned char *ctx, unsigned long long ctxlen,
                                 const unsigned char *ad, unsigned long long adlen,
                                 const unsigned char *t)
{
    unsigned long long i;
    int j, k;
    unsigned char *yprim;
    unsigned char *y;
    unsigned char *xprim;
    unsigned char *x;
    const unsigned char *m;
    const unsigned char *mnext;
    unsigned char* tprim;

    tprim = (unsigned char*)malloc(BLOCK_BYTE_SIZE * sizeof(unsigned char));

    x = (unsigned char*)malloc(2 * BLOCK_BYTE_SIZE * sizeof(unsigned char));
    xprim = x + BLOCK_BYTE_SIZE; // xprim points to second half of memory

    y = (unsigned char*)malloc(2 * BLOCK_BYTE_SIZE * sizeof(unsigned char));
    yprim = y + BLOCK_BYTE_SIZE; // yprim points to second half of memory

    if(x == 0x0 || xprim == 0x0 || y == 0x0 || yprim == 0x0)
        return -2;

    // initial xprim, x, m0 and m1
    m = noc;
    mnext = ad;
    for(i=0 ; i<BLOCK_BYTE_SIZE ; i++){
        xprim[i] = noc[i];
        x[i] = key[i];
    }

    // Process associated data
    if(adlen != 0){
        unsigned long long ab = adlen / BLOCK_BYTE_SIZE;    // number of complete blocks of associated data
        // Process complete blocks of associated data
        for(i=0 ; i<ab ; i++){
            artemia_permutation(x, y);
            for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
                xprim[j] = yprim[j] ^ mnext[j];
                x[j] = y[j] ^ m[j];
            }
            m = mnext;
            mnext += BLOCK_BYTE_SIZE;
        }
        // Padding last block of AD and process it
        unsigned char* padded;
        padded = padding_associated_data(mnext, adlen % BLOCK_BYTE_SIZE, &k);
        mnext = padded;
        for(i=0 ; i<k/BLOCK_BYTE_SIZE ; i++){
            artemia_permutation(x, y);
            for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
                xprim[j] = yprim[j] ^ mnext[j];
                x[j] = y[j] ^ m[j];
            }
            m = mnext;
            mnext += BLOCK_BYTE_SIZE;
        }
    }

    // Process ciphertext
    unsigned long long cb = ctxlen / BLOCK_BYTE_SIZE;   // number of blocks of ciphertext
    for(i=0 ; i<cb ; i++){
        artemia_permutation(x, y);
        for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
            xprim[j] = ctx[i * BLOCK_BYTE_SIZE + j];    // prepare xprim for next permutation
            msg[i * BLOCK_BYTE_SIZE + j] = yprim[j] ^ xprim[j]; // Storing message
            x[j] = y[j] ^ m[j];
        }
        m = msg + i * BLOCK_BYTE_SIZE;
    }

    // final step
    artemia_permutation(x, y);
    for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
        //x[j] = y[j] ^ m[j];
        tprim[j] = y[j] ^ m[j] ^ key[j];
    }

    // Unpadding
    *msglen = unpadding_message_inplace(msg, ctxlen);

    int result = 0;
    // Check if T = Tprim
    for(j=0 ; j<BLOCK_BYTE_SIZE ; j++)
        if(tprim[j] != t[j]){
            result = -1; // Encryption Fail
            memset(msg, 0, (*msglen) * sizeof(unsigned char)); // clear output
            break;
        }

    m = mnext = 0x0;
    xprim = yprim = 0x0;
    free(y);
    free(x);
    free(tprim);

    return result;
}
int jhae_encryption_authentication(unsigned char *c, unsigned long long *clen,
                                  unsigned char *t,
                                  const unsigned char *key,
                                  const unsigned char *noc,
                                  const unsigned char *msg, unsigned long long msglen,
                                  const unsigned char *ad, unsigned long long adlen)
{
    unsigned long long i;
    int j, k;
    unsigned char *yprim;
    unsigned char *y;
    unsigned char *xprim;
    unsigned char *x;
    const unsigned char *m;
    const unsigned char *mnext;

    i = msglen + 13;
    i += i % BLOCK_BYTE_SIZE == 0 ? 0 : BLOCK_BYTE_SIZE - (i % BLOCK_BYTE_SIZE);
    *clen = i;

    x = (unsigned char*)malloc(2 * BLOCK_BYTE_SIZE * sizeof(unsigned char));
    xprim = x + BLOCK_BYTE_SIZE; // xprim points to second half of memory

    y = (unsigned char*)malloc(2 * BLOCK_BYTE_SIZE * sizeof(unsigned char));
    yprim = y + BLOCK_BYTE_SIZE; // y points to second half of memory

    if(x == 0x0 || xprim == 0x0 || y == 0x0 || yprim == 0x0)
        return -2;

    // initial xprim, x, m0 and m1
    m = noc;
    mnext = ad;
    for(i=0 ; i<BLOCK_BYTE_SIZE ; i++){
        xprim[i] = noc[i];
        x[i] = key[i];
    }

    // Process associated data
    if(adlen != 0){
        unsigned long long ab = adlen / BLOCK_BYTE_SIZE;    // number of complete blocks of associated data
        // Process complete blocks of associated data
        for(i=0 ; i<ab ; i++){
            artemia_permutation(x, y);
            for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
                xprim[j] = yprim[j] ^ mnext[j];
                x[j] = y[j] ^ m[j];
            }
            m = mnext;
            mnext += BLOCK_BYTE_SIZE;
        }
        // Padding last block of AD and process it
        unsigned char* padded;
        padded = padding_associated_data(mnext, adlen % BLOCK_BYTE_SIZE, &k);
        mnext = padded;
        for(i=0 ; i<k/BLOCK_BYTE_SIZE ; i++){
            artemia_permutation(x, y);
            for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
                xprim[j] = yprim[j] ^ mnext[j];
                x[j] = y[j] ^ m[j];
            }
            m = mnext;
            mnext += BLOCK_BYTE_SIZE;
        }
    }

    // Process message
    unsigned long long mb = msglen / BLOCK_BYTE_SIZE; // number of complete blocks of message
    // Process complete blocks of message
    mnext = msg;
    for(i=0 ; i<mb ; i++){
        artemia_permutation(x, y);
        for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
            xprim[j] = yprim[j] ^ mnext[j];
            x[j] = y[j] ^ m[j];
            c[i * BLOCK_BYTE_SIZE + j] = xprim[j]; // Storing ciphertext
        }
        m = mnext;
        mnext += BLOCK_BYTE_SIZE;
    }
    // Padding last block of message and process it
    unsigned char* padded;
    padded = padding_message(mnext, msglen % BLOCK_BYTE_SIZE, msglen, noc, ad, adlen, &k);
    mnext = padded;
    for(i=0 ; i<k/BLOCK_BYTE_SIZE ; i++){
        artemia_permutation(x, y);
        for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
            xprim[j] = yprim[j] ^ mnext[j];
            x[j] = y[j] ^ m[j];
            c[(mb + i) * BLOCK_BYTE_SIZE + j] = xprim[j]; // Storing ciphertext
        }
        m = mnext;
        mnext += BLOCK_BYTE_SIZE;
    }
    // final step
    artemia_permutation(x, y);
    for(j=0 ; j<BLOCK_BYTE_SIZE ; j++){
        //x[j] = y[j] ^ m[j];
        t[j] = y[j] ^ m[j] ^ key[j];
    }

    m = mnext = 0x0;
    xprim = yprim = NULL;
    free(x);
    free(y);

    return 0;
}