Browse Source

NaCl draft

master
Igor Zhukov 10 years ago
parent
commit
2c49f28b7d
  1. 48
      app/js/lib/ng_utils.js
  2. 63
      app/nacl/Makefile
  3. 147
      app/nacl/aes.h
  4. 1358
      app/nacl/aes_core.c
  5. 325
      app/nacl/aes_ige.c
  6. 89
      app/nacl/aes_locl.h
  7. 85
      app/nacl/aes_misc.c
  8. BIN
      app/nacl/mtproto_crypto.bc
  9. 157
      app/nacl/mtproto_crypto.cc
  10. 9
      app/nacl/mtproto_crypto.nmf
  11. BIN
      app/nacl/mtproto_crypto.pexe
  12. 3
      server.js

48
app/js/lib/ng_utils.js

@ -488,25 +488,44 @@ angular.module('izhukov.utils', [])
taskID = 0, taskID = 0,
awaiting = {}, awaiting = {},
webCrypto = window.crypto && (window.crypto.subtle || window.crypto.webkitSubtle) || window.msCrypto && window.msCrypto.subtle, webCrypto = window.crypto && (window.crypto.subtle || window.crypto.webkitSubtle) || window.msCrypto && window.msCrypto.subtle,
useSha1Crypto = webCrypto && webCrypto.digest !== undefined; useSha1Crypto = webCrypto && webCrypto.digest !== undefined,
aesNaClEmbed = false,
finalizeTask = function (taskID, result) {
var deferred = awaiting[taskID];
if (deferred !== undefined) {
console.log(dT(), 'CW done');
deferred.resolve(result);
delete awaiting[taskID];
}
};
if (navigator.mimeTypes['application/x-pnacl'] !== undefined) {
var listener = $('<div id="nacl_listener"><embed id="mtproto_crypto" width="0" height="0" src="nacl/mtproto_crypto.nmf" type="application/x-pnacl" /></div>').appendTo($('body'))[0];
listener.addEventListener('load', function (e) {
aesNaClEmbed = listener.firstChild;
console.warn('NaCl ready', aesNaClEmbed);
}, true);
listener.addEventListener('message', function (e) {
console.log(e.data.result);
console.log(bytesFromArrayBuffer(e.data.result));
finalizeTask(e.data.taskID, e.data.result);
}, true);
listener.addEventListener('error', function (e) {
console.error(e);
}, true);
}
if (worker) { if (worker) {
worker.onmessage = function (e) { worker.onmessage = function (e) {
var deferred = awaiting[e.data.taskID]; finalizeTask(e.data.taskID, e.data.result);
if (deferred !== undefined) {
console.log(dT(), 'CW done');
deferred.resolve(e.data.result);
delete awaiting[e.data.taskID];
}
}; };
worker.onerror = function(error) { worker.onerror = function(error) {
console.error('CW error', error, error.stack); console.error('CW error', error, error.stack);
worker = false; worker = false;
}; };
} }
function performTaskWorker (task, params) { function performTaskWorker (task, params, embed) {
console.log(dT(), 'CW start', task); console.log(dT(), 'CW start', task);
var deferred = $q.defer(); var deferred = $q.defer();
@ -514,7 +533,7 @@ angular.module('izhukov.utils', [])
params.task = task; params.task = task;
params.taskID = taskID; params.taskID = taskID;
worker.postMessage(params); (embed || worker).postMessage(params);
taskID++; taskID++;
@ -547,12 +566,19 @@ angular.module('izhukov.utils', [])
}); });
}, },
aesEncrypt: function (bytes, keyBytes, ivBytes) { aesEncrypt: function (bytes, keyBytes, ivBytes) {
if (aesNaClEmbed) {
return performTaskWorker('aes-encrypt', {
bytes: bytes,
keyBytes: bytesToArrayBuffer(keyBytes),
ivBytes: bytesToArrayBuffer(ivBytes)
}, aesNaClEmbed);
}
if (worker && false) { // due overhead for data transfer if (worker && false) { // due overhead for data transfer
return performTaskWorker('aes-encrypt', { return performTaskWorker('aes-encrypt', {
bytes: bytes, bytes: bytes,
keyBytes: keyBytes, keyBytes: keyBytes,
ivBytes: ivBytes ivBytes: ivBytes
}); }, aesNaClEmbed);
} }
return $timeout(function () { return $timeout(function () {
return aesEncrypt(bytes, keyBytes, ivBytes); return aesEncrypt(bytes, keyBytes, ivBytes);

63
app/nacl/Makefile

@ -0,0 +1,63 @@
# Copyright (c) 2013 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# GNU Make based build file.  For details on GNU Make see:
# http://www.gnu.org/software/make/manual/make.html
#
#
# Get pepper directory for toolchain and includes.
#
# If NACL_SDK_ROOT is not set, then assume it can be found three directories up.
#
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
NACL_SDK_ROOT ?= $(abspath $(dir $(THIS_MAKEFILE))../..)
# Project Build flags
WARNINGS := -Wno-long-long -Wall -Wswitch-enum -pedantic -Werror
CXXFLAGS := -pthread -std=gnu++98 $(WARNINGS)
#
# Compute tool paths
#
GETOS := python $(NACL_SDK_ROOT)/tools/getos.py
OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py
OSNAME := $(shell $(GETOS))
RM := $(OSHELPERS) rm
PNACL_TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_pnacl)
PNACL_CXX := $(PNACL_TC_PATH)/bin/pnacl-clang++
PNACL_FINALIZE := $(PNACL_TC_PATH)/bin/pnacl-finalize
CXXFLAGS := -I$(NACL_SDK_ROOT)/include
LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_cpp -lppapi
#
# Disable DOS PATH warning when using Cygwin based tools Windows
#
CYGWIN ?= nodosfilewarning
export CYGWIN
# Declare the ALL target first, to make the 'all' target the default build
all: mtproto_crypto.pexe
clean:
$(RM) mtproto_crypto.pexe mtproto_crypto.bc
mtproto_crypto.bc: mtproto_crypto.cc aes_core.c aes_ige.c aes_misc.c
$(PNACL_CXX) -o $@ $^ -O2 $(CXXFLAGS) $(LDFLAGS)
mtproto_crypto.pexe: mtproto_crypto.bc
$(PNACL_FINALIZE) -o $@ $<
#
# Makefile target to run the SDK's simple HTTP server and serve this example.
#
HTTPD_PY := python $(NACL_SDK_ROOT)/tools/httpd.py
.PHONY: serve
serve: all
$(HTTPD_PY) -C $(CURDIR)

147
app/nacl/aes.h

@ -0,0 +1,147 @@
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#ifndef HEADER_AES_H
#define HEADER_AES_H
//#include <openssl/opensslconf.h>
#ifdef OPENSSL_NO_AES
#error AES is disabled.
#endif
#include <stddef.h>
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
/* Because array size can't be a const in C, the following two are macros.
Both sizes are in bytes. */
#define AES_MAXNR 14
#define AES_BLOCK_SIZE 16
#ifdef __cplusplus
extern "C" {
#endif
/* This should be a hidden type, but EVP requires that the size be known */
struct aes_key_st {
#ifdef AES_LONG
unsigned long rd_key[4 *(AES_MAXNR + 1)];
#else
unsigned int rd_key[4 *(AES_MAXNR + 1)];
#endif
int rounds;
};
typedef struct aes_key_st AES_KEY;
const char *AES_options(void);
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, const int enc);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num);
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char ivec[AES_BLOCK_SIZE],
unsigned char ecount_buf[AES_BLOCK_SIZE],
unsigned int *num);
/* NB: the IV is _two_ blocks long */
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
/* NB: the IV is _four_ blocks long */
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
const AES_KEY *key2, const unsigned char *ivec,
const int enc);
int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen);
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen);
#ifdef __cplusplus
}
#endif
#endif /* !HEADER_AES_H */

1358
app/nacl/aes_core.c

File diff suppressed because it is too large Load Diff

325
app/nacl/aes_ige.c

@ -0,0 +1,325 @@
/* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
//#include "cryptlib.h"
#include "aes.h"
#include "aes_locl.h"
#include <assert.h>
#define OPENSSL_assert assert
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
typedef struct {
unsigned long data[N_WORDS];
} aes_block_t;
/* XXX: probably some better way to do this */
#if defined(__i386__) || defined(__x86_64__)
#define UNALIGNED_MEMOPS_ARE_FAST 1
#else
#define UNALIGNED_MEMOPS_ARE_FAST 0
#endif
#if UNALIGNED_MEMOPS_ARE_FAST
#define load_block(d, s) (d) = *(const aes_block_t *)(s)
#define store_block(d, s) *(aes_block_t *)(d) = (s)
#else
#define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE)
#define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE)
#endif
/* N.B. The IV for this mode is _twice_ the block size */
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc)
{
size_t n;
size_t len = length;
OPENSSL_assert(in && out && key && ivec);
OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
len = length / AES_BLOCK_SIZE;
if (AES_ENCRYPT == enc)
{
if (in != out &&
(UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
{
aes_block_t *ivp = (aes_block_t *)ivec;
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
while (len)
{
aes_block_t *inp = (aes_block_t *)in;
aes_block_t *outp = (aes_block_t *)out;
for(n=0 ; n < N_WORDS; ++n)
outp->data[n] = inp->data[n] ^ ivp->data[n];
AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
for(n=0 ; n < N_WORDS; ++n)
outp->data[n] ^= iv2p->data[n];
ivp = outp;
iv2p = inp;
--len;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
}
else
{
aes_block_t tmp, tmp2;
aes_block_t iv;
aes_block_t iv2;
load_block(iv, ivec);
load_block(iv2, ivec + AES_BLOCK_SIZE);
while (len)
{
load_block(tmp, in);
for(n=0 ; n < N_WORDS; ++n)
tmp2.data[n] = tmp.data[n] ^ iv.data[n];
AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key);
for(n=0 ; n < N_WORDS; ++n)
tmp2.data[n] ^= iv2.data[n];
store_block(out, tmp2);
iv = tmp2;
iv2 = tmp;
--len;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
}
}
else
{
if (in != out &&
(UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
{
aes_block_t *ivp = (aes_block_t *)ivec;
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
while (len)
{
aes_block_t tmp;
aes_block_t *inp = (aes_block_t *)in;
aes_block_t *outp = (aes_block_t *)out;
for(n=0 ; n < N_WORDS; ++n)
tmp.data[n] = inp->data[n] ^ iv2p->data[n];
AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key);
for(n=0 ; n < N_WORDS; ++n)
outp->data[n] ^= ivp->data[n];
ivp = inp;
iv2p = outp;
--len;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
}
else
{
aes_block_t tmp, tmp2;
aes_block_t iv;
aes_block_t iv2;
load_block(iv, ivec);
load_block(iv2, ivec + AES_BLOCK_SIZE);
while (len)
{
load_block(tmp, in);
tmp2 = tmp;
for(n=0 ; n < N_WORDS; ++n)
tmp.data[n] ^= iv2.data[n];
AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key);
for(n=0 ; n < N_WORDS; ++n)
tmp.data[n] ^= iv.data[n];
store_block(out, tmp);
iv = tmp2;
iv2 = tmp;
--len;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
}
}
}
/*
* Note that its effectively impossible to do biIGE in anything other
* than a single pass, so no provision is made for chaining.
*/
/* N.B. The IV for this mode is _four times_ the block size */
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
const AES_KEY *key2, const unsigned char *ivec,
const int enc)
{
size_t n;
size_t len = length;
unsigned char tmp[AES_BLOCK_SIZE];
unsigned char tmp2[AES_BLOCK_SIZE];
unsigned char tmp3[AES_BLOCK_SIZE];
unsigned char prev[AES_BLOCK_SIZE];
const unsigned char *iv;
const unsigned char *iv2;
OPENSSL_assert(in && out && key && ivec);
OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
if (AES_ENCRYPT == enc)
{
/* XXX: Do a separate case for when in != out (strictly should
check for overlap, too) */
/* First the forward pass */
iv = ivec;
iv2 = ivec + AES_BLOCK_SIZE;
while (len >= AES_BLOCK_SIZE)
{
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
out[n] = in[n] ^ iv[n];
AES_encrypt(out, out, key);
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
out[n] ^= iv2[n];
iv = out;
memcpy(prev, in, AES_BLOCK_SIZE);
iv2 = prev;
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
/* And now backwards */
iv = ivec + AES_BLOCK_SIZE*2;
iv2 = ivec + AES_BLOCK_SIZE*3;
len = length;
while(len >= AES_BLOCK_SIZE)
{
out -= AES_BLOCK_SIZE;
/* XXX: reduce copies by alternating between buffers */
memcpy(tmp, out, AES_BLOCK_SIZE);
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
out[n] ^= iv[n];
/* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */
AES_encrypt(out, out, key);
/* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */
/* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
out[n] ^= iv2[n];
/* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */
iv = out;
memcpy(prev, tmp, AES_BLOCK_SIZE);
iv2 = prev;
len -= AES_BLOCK_SIZE;
}
}
else
{
/* First backwards */
iv = ivec + AES_BLOCK_SIZE*2;
iv2 = ivec + AES_BLOCK_SIZE*3;
in += length;
out += length;
while (len >= AES_BLOCK_SIZE)
{
in -= AES_BLOCK_SIZE;
out -= AES_BLOCK_SIZE;
memcpy(tmp, in, AES_BLOCK_SIZE);
memcpy(tmp2, in, AES_BLOCK_SIZE);
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
tmp[n] ^= iv2[n];
AES_decrypt(tmp, out, key);
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
out[n] ^= iv[n];
memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
iv = tmp3;
iv2 = out;
len -= AES_BLOCK_SIZE;
}
/* And now forwards */
iv = ivec;
iv2 = ivec + AES_BLOCK_SIZE;
len = length;
while (len >= AES_BLOCK_SIZE)
{
memcpy(tmp, out, AES_BLOCK_SIZE);
memcpy(tmp2, out, AES_BLOCK_SIZE);
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
tmp[n] ^= iv2[n];
AES_decrypt(tmp, out, key);
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
out[n] ^= iv[n];
memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
iv = tmp3;
iv2 = out;
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
}
}

89
app/nacl/aes_locl.h

@ -0,0 +1,89 @@
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#ifndef HEADER_AES_LOCL_H
#define HEADER_AES_LOCL_H
//#include <openssl/e_os2.h>
#ifdef OPENSSL_NO_AES
#error AES is disabled.
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
# define GETU32(p) SWAP(*((u32 *)(p)))
# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
#else
# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
#endif
#ifdef AES_LONG
typedef unsigned long u32;
#else
typedef unsigned int u32;
#endif
typedef unsigned short u16;
typedef unsigned char u8;
#define MAXKC (256/32)
#define MAXKB (256/8)
#define MAXNR 14
/* This controls loop-unrolling in aes_core.c */
#undef FULL_UNROLL
#endif /* !HEADER_AES_LOCL_H */

85
app/nacl/aes_misc.c

@ -0,0 +1,85 @@
/* crypto/aes/aes_misc.c -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
//#include <openssl/opensslv.h>
//#include <openssl/crypto.h>
#include "aes.h"
#include "aes_locl.h"
const char AES_version[]="AES" ;//OPENSSL_VERSION_PTEXT;
const char *AES_options(void) {
#ifdef FULL_UNROLL
return "aes(full)";
#else
return "aes(partial)";
#endif
}
/* FIPS wrapper functions to block low level AES calls in FIPS mode */
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key)
{
#ifdef OPENSSL_FIPS
fips_cipher_abort(AES);
#endif
return private_AES_set_encrypt_key(userKey, bits, key);
}
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key)
{
#ifdef OPENSSL_FIPS
fips_cipher_abort(AES);
#endif
return private_AES_set_decrypt_key(userKey, bits, key);
}

BIN
app/nacl/mtproto_crypto.bc

Binary file not shown.

157
app/nacl/mtproto_crypto.cc

@ -0,0 +1,157 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// @file hello_tutorial.cc
/// This example demonstrates loading, running and scripting a very simple NaCl
/// module. To load the NaCl module, the browser first looks for the
/// CreateModule() factory method (at the end of this file). It calls
/// CreateModule() once to load the module code. After the code is loaded,
/// CreateModule() is not called again.
///
/// Once the code is loaded, the browser calls the CreateInstance()
/// method on the object returned by CreateModule(). It calls CreateInstance()
/// each time it encounters an <embed> tag that references your NaCl module.
///
/// The browser can talk to your NaCl module via the postMessage() Javascript
/// function. When you call postMessage() on your NaCl module from the browser,
/// this becomes a call to the HandleMessage() method of your pp::Instance
/// subclass. You can send messages back to the browser by calling the
/// PostMessage() method on your pp::Instance. Note that these two methods
/// (postMessage() in Javascript and PostMessage() in C++) are asynchronous.
/// This means they return immediately - there is no waiting for the message
/// to be handled. This has implications in your program design, particularly
/// when mutating property values that are exposed to both the browser and the
/// NaCl module.
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/cpp/var_array_buffer.h"
#include "aes.h"
namespace {
const char* const kDataKeyString = "bytes";
const char* const kKeyKeyString = "keyBytes";
const char* const kIvKeyString = "ivBytes";
} // namespace
/// The Instance class. One of these exists for each instance of your NaCl
/// module on the web page. The browser will ask the Module object to create
/// a new Instance for each occurrence of the <embed> tag that has these
/// attributes:
/// src="hello_tutorial.nmf"
/// type="application/x-pnacl"
/// To communicate with the browser, you must override HandleMessage() to
/// receive messages from the browser, and use PostMessage() to send messages
/// back to the browser. Note that this interface is asynchronous.
class MtprotoCryptoInstance : public pp::Instance {
public:
/// The constructor creates the plugin-side instance.
/// @param[in] instance the handle to the browser-side plugin instance.
explicit MtprotoCryptoInstance(PP_Instance instance) : pp::Instance(instance)
{}
virtual ~MtprotoCryptoInstance() {}
/// Handler for messages coming in from the browser via postMessage(). The
/// @a var_message can contain be any pp:Var type; for example int, string
/// Array or Dictinary. Please see the pp:Var documentation for more details.
/// @param[in] var_message The message posted by the browser.
virtual void HandleMessage(const pp::Var& var_message) {
// if (1) {
// PostMessage(var_message);
// return;
// }
if (!var_message.is_dictionary()) {
return;
}
pp::VarDictionary request = pp::VarDictionary::VarDictionary(var_message);
pp::Var varTaskID = request.Get(pp::Var::Var("taskID"));
pp::Var varTask = request.Get(pp::Var::Var("task"));
if (!varTaskID.is_int()) {
return;
}
int32_t intTaskID = varTaskID.AsInt();
std::string strTask = varTask.AsString();
pp::Var varResult;// = pp::Var::Var();
if (strTask == "aes-encrypt") {
pp::Var varData = request.Get(pp::Var::Var("bytes"));
pp::Var varKey = request.Get(pp::Var::Var("keyBytes"));
pp::Var varIv = request.Get(pp::Var::Var("ivBytes"));
if (!varData.is_array_buffer() || !varKey.is_array_buffer() || !varIv.is_array_buffer()) {
return;
}
pp::VarArrayBuffer abData = pp::VarArrayBuffer::VarArrayBuffer(varData);
pp::VarArrayBuffer abKey = pp::VarArrayBuffer::VarArrayBuffer(varKey);
pp::VarArrayBuffer abIv = pp::VarArrayBuffer::VarArrayBuffer(varIv);
int length = abData.ByteLength();
char* what = static_cast<char*>(abData.Map());
char* keyBuff = static_cast<char*>(abKey.Map());
char* ivBuff = static_cast<char*>(abIv.Map());
AES_KEY akey;
AES_set_encrypt_key((const unsigned char *) keyBuff, 32 * 8, &akey);
AES_ige_encrypt((const unsigned char *)what, (unsigned char *)what, length, &akey, (unsigned char *)ivBuff, AES_DECRYPT);
// varResult = pp::Var::Var(what);
// varResult = pp::VarArrayBuffer::VarArrayBuffer(pp::Var::Var(what));
abData.Unmap();
varResult = abData;
// varResult = pp::VarArrayBuffer::VarArrayBuffer();
// pp::VarArrayBuffer varResult(what);
} else {
varResult = pp::Var::Var();
}
pp::VarDictionary response = pp::VarDictionary::VarDictionary();
response.Set(pp::Var::Var("taskID"), varTaskID);
response.Set(pp::Var::Var("result"), varResult);
PostMessage(response);
// std::string message = var_message.AsString();
// pp::Var var_reply;
// if (message == kHelloString) {
// var_reply = pp::Var(kReplyString);
// PostMessage(var_reply);
// }
}
};
/// The Module class. The browser calls the CreateInstance() method to create
/// an instance of your NaCl module on the web page. The browser creates a new
/// instance for each <embed> tag with type="application/x-pnacl".
class MtprotoCryptoModule : public pp::Module {
public:
MtprotoCryptoModule() : pp::Module() {}
virtual ~MtprotoCryptoModule() {}
/// Create and return a MtprotoCryptoInstance object.
/// @param[in] instance The browser-side instance.
/// @return the plugin-side instance.
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new MtprotoCryptoInstance(instance);
}
};
namespace pp {
/// Factory function called by the browser when the module is first loaded.
/// The browser keeps a singleton of this module. It calls the
/// CreateInstance() method on the object you return to make instances. There
/// is one instance per <embed> tag on the page. This is the main binding
/// point for your NaCl module with the browser.
Module* CreateModule() {
return new MtprotoCryptoModule();
}
} // namespace pp

9
app/nacl/mtproto_crypto.nmf

@ -0,0 +1,9 @@
{
"program": {
"portable": {
"pnacl-translate": {
"url": "mtproto_crypto.pexe?13"
}
}
}
}

BIN
app/nacl/mtproto_crypto.pexe

Binary file not shown.

3
server.js

@ -88,7 +88,8 @@ StaticServlet.MimeMap = {
'png': 'image/png', 'png': 'image/png',
  'svg': 'image/svg+xml',   'svg': 'image/svg+xml',
  'wav': 'audio/wav',   'wav': 'audio/wav',
'ico': 'image/vnd.microsoft.icon' 'ico': 'image/vnd.microsoft.icon',
'pexe': 'application/x-pnacl'
}; };
StaticServlet.prototype.handleRequest = function(req, res) { StaticServlet.prototype.handleRequest = function(req, res) {

Loading…
Cancel
Save