void xs_stream_encrypt(xsMachine *the) { crypt_stream_t *stream = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc); size_t len; void *indata, *outdata; if (xsTypeOf(xsArg(0)) == xsStringType) len = strlen(xsToString(xsArg(0))); else len = xsGetArrayBufferLength(xsArg(0)); if (ac > 2 && xsTypeOf(xsArg(2)) != xsUndefinedType) { size_t n = xsToInteger(xsArg(2)); if (n < len) len = n; } xsResult = ac > 1 && xsTest(xsArg(1)) ? xsArg(1) : xsArrayBuffer(NULL, len); if (xsTypeOf(xsArg(0)) == xsStringType) indata = xsToString(xsArg(0)); else indata = xsToArrayBuffer(xsArg(0)); outdata = xsToArrayBuffer(xsResult); (*stream->process)(stream->ctx, indata, outdata, len); }
static void cipher_process(xsMachine *the, kcl_symmetric_direction_t direction) { crypt_cipher_t *cipher = xsGetHostData(xsThis); size_t len; void *indata, *outdata; if (cipher->keysched != NULL) { if (cipher->direction != direction) { (*cipher->keysched)(cipher->ctx, direction); cipher->direction = direction; } } if (xsToInteger(xsArgc) > 1 && xsTest(xsArg(1))) { if (xsGetArrayBufferLength(xsArg(1)) < (xsIntegerValue)cipher->blockSize) crypt_throw_error(the, "cipher: too small buffer"); xsResult = xsArg(1); } else xsResult = xsArrayBuffer(NULL, cipher->blockSize); if (xsTypeOf(xsArg(0)) == xsStringType) { indata = xsToString(xsArg(0)); len = c_strlen(indata); } else { indata = xsToArrayBuffer(xsArg(0)); len = xsGetArrayBufferLength(xsArg(0)); } if (len < cipher->blockSize) crypt_throw_error(the, "cipher: wrong size"); outdata = xsToArrayBuffer(xsResult); (*cipher->process)(cipher->ctx, indata, outdata); }
void xs_stream_encrypt(xsMachine *the) { crypt_stream_t *stream = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc); size_t len; void *indata, *outdata; if (xsTypeOf(xsArg(0)) == xsStringType) len = c_strlen(xsToString(xsArg(0))); else len = xsGetArrayBufferLength(xsArg(0)); if (ac > 2 && xsTypeOf(xsArg(2)) != xsUndefinedType) { size_t n = xsToInteger(xsArg(2)); if (n < len) len = n; } if (ac > 1 && xsTest(xsArg(1))) { if (xsGetArrayBufferLength(xsArg(1)) < (xsIntegerValue)len) crypt_throw_error(the, "too small buffer"); xsResult = xsArg(1); } else xsResult = xsArrayBuffer(NULL, len); if (xsTypeOf(xsArg(0)) == xsStringType) indata = xsToString(xsArg(0)); else indata = xsToArrayBuffer(xsArg(0)); outdata = xsToArrayBuffer(xsResult); (*stream->process)(stream->ctx, indata, outdata, len); }
void xs_chacha_init(xsMachine *the) { crypt_stream_t *stream = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc); void *key, *iv; size_t keysize, ivsize; uint64_t counter = 0; kcl_err_t err; key = xsToArrayBuffer(xsArg(0)); keysize = xsGetArrayBufferLength(xsArg(0)); if (ac > 1 && xsTest(xsArg(1))) { iv = xsToArrayBuffer(xsArg(1)); ivsize = xsGetArrayBufferLength(xsArg(1)); } else { iv = NULL; ivsize = 0; } if (ac > 2) { switch (xsTypeOf(xsArg(2))) { case xsIntegerType: case xsNumberType: counter = xsToInteger(xsArg(2)); /* @@ take only 32bit */ break; } } if ((err = kcl_chacha_init(&stream->ctx, key, keysize, iv, ivsize, counter)) != KCL_ERR_NONE) kcl_throw_error(the, err); stream->process = kcl_chacha_process; stream->finish = kcl_chacha_finish; }
void KPR_mqttclient_publish(xsMachine* the) { KPR_MQTTClientRecord *self = xsGetHostData(xsThis); FskErr err = kFskErrNone; char *topic; void *payload = NULL; UInt32 payloadLength = 0; UInt8 qos; Boolean retain; UInt16 token; if (xsToInteger(xsArgc) != 4) xsThrowIfFskErr(kFskErrParameterError); topic = xsToString(xsArg(0)); if (xsTest(xsArg(1))) { if (isArrayBuffer(xsArg(1))) { payload = xsToArrayBuffer(xsArg(1)); payloadLength = xsGetArrayBufferLength(xsArg(1)); } else { payload = xsToString(xsArg(1)); payloadLength = FskStrLen(payload); } } qos = xsToInteger(xsArg(2)); retain = xsToBoolean(xsArg(3)); bailIfError(KprMQTTClientPublish(self->client, topic, payload, payloadLength, qos, retain, &token)); xsResult = xsInteger(token); bail: xsThrowIfFskErr(err); }
void xs_system_init_rng(xsMachine *the) { size_t sz; void *data; switch (xsTypeOf(xsArg(0))) { case xsIntegerType: case xsNumberType: { unsigned long n = xsToNumber(xsArg(0)); data = &n; sz = sizeof(long); break; } case xsStringType: { char *s = xsToString(xsArg(0)); data = s; sz = strlen(s); break; } default: if (xsIsInstanceOf(xsArg(0), xsArrayBufferPrototype)) { data = xsToArrayBuffer(xsArg(0)); sz = xsGetArrayBufferLength(xsArg(0)); } else { data = NULL; sz = 0; } break; } mc_rng_init(data, sz); }
void xs_chacha_setIV(xsMachine *the) { crypt_stream_t *stream = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc); void *iv; size_t ivsize; uint64_t counter = 0; if (ac > 0 && xsTest(xsArg(0))) { iv = xsToArrayBuffer(xsArg(0)); ivsize = xsGetArrayBufferLength(xsArg(0)); } else { iv = NULL; ivsize = 0; } if (ac > 1) { switch (xsTypeOf(xsArg(1))) { case xsIntegerType: case xsNumberType: counter = xsToInteger(xsArg(1)); /* @@ take only 32bit */ break; } } kcl_chacha_setIV(stream->ctx, iv, ivsize, counter); }
void xs_rng_get(xsMachine *the) { size_t n = xsToInteger(xsArg(0)); uint8_t *bp, *bufend; uint8_t i, j, t; if (!rng_inited) { /* use srand */ #define DEFAULT_SEED_SIZE 16 uint8_t seed[DEFAULT_SEED_SIZE]; for (i = 0; i < DEFAULT_SEED_SIZE; i++) seed[i] = ((uint64_t)c_rand() * 256) / C_RAND_MAX; rng_init(seed, DEFAULT_SEED_SIZE); rng_inited++; } xsResult = xsArrayBuffer(NULL, n); bp = xsToArrayBuffer(xsResult); for (i = j = 0, bufend = bp + n; bp < bufend;) { ++i; j += rng_state[i]; t = rng_state[i]; rng_state[i] = rng_state[j]; rng_state[j] = t; t = rng_state[i] + rng_state[j]; *bp++ = rng_state[t]; } }
void xs_curve25519_dh(xsMachine *the) { void *secret, *basepoint; xsResult = xsArrayBuffer(NULL, C25519_EXPONENT_SIZE); secret = xsToArrayBuffer(xsArg(0)); if (xsToInteger(xsArgc) > 1) { if (xsGetArrayBufferLength(xsArg(1)) != 32) xsRangeError("bad arg"); basepoint = xsToArrayBuffer(xsArg(1)); } else basepoint = (void *)c25519_base_x; c25519_prepare(secret); c25519_smult(xsToArrayBuffer(xsResult), basepoint, secret); }
void xs_digest_close(xsMachine *the) { crypt_digest_t *digest = xsGetHostData(xsThis); xsResult = xsArrayBuffer(NULL, digest->outputSize); (*digest->result)(digest->ctx, xsToArrayBuffer(xsResult)); }
void xs_system_init_key(xsMachine *the) { void *data = xsToArrayBuffer(xsArg(0)); size_t sz = xsGetArrayBufferLength(xsArg(0)); mc_srng_init(data, sz); }
void xs_system_get_rng(xsMachine *the) { int sz = xsToInteger(xsArg(0)); xsResult = xsArrayBuffer(NULL, sz); mc_rng_gen((uint8_t *)xsToArrayBuffer(xsResult), sz); }
void xs_rng_get(xsMachine *the) { size_t n = xsToInteger(xsArg(0)); xsResult = xsArrayBuffer(NULL, n); crypt_rng(xsToArrayBuffer(xsResult), n); }
void KPR_message_get_responseBuffer(xsMachine *the) { KprMessage self = xsGetHostData(xsThis); void* data; UInt32 size; KprMessageGetResponseBody(self, &data, &size); if (data && size) { xsResult = xsNew1(xsGlobal, xsID_ArrayBuffer, xsInteger(size)); FskMemMove(xsToArrayBuffer(xsResult), data, size); } }
void KPR_message_set_responseBuffer(xsMachine* the) { KprMessage self = xsGetHostData(xsThis); if (xsTest(xsArg(0))) { void* data = xsToArrayBuffer(xsArg(0)); xsIntegerValue size = xsGetArrayBufferLength(xsArg(0)); xsThrowIfFskErr(KprMessageSetResponseBody(self, data, size)); } else xsThrowIfFskErr(KprMessageSetResponseBody(self, NULL, 0)); }
void xs_rng_init(xsMachine *the) { int i; for (i = 0; i < 256; i++) rng_state[i] = i; if (xsToInteger(xsArgc) > 0 && xsTest(xsArg(0))) { uint8_t *seed = xsToArrayBuffer(xsArg(0)); size_t seedsize = xsGetArrayBufferLength(xsArg(0)); rng_init(seed, seedsize); } rng_inited++; }
void xs_tdes_init(xsMachine *the) { crypt_cipher_t *cipher = xsGetHostData(xsThis); void *key; size_t keysize; kcl_err_t err; key = xsToArrayBuffer(xsArg(0)); keysize = xsGetArrayBufferLength(xsArg(0)); if ((err = kcl_tdes_init(&cipher->ctx, key, keysize)) != KCL_ERR_NONE) kcl_throw_error(the, err); cipher->keysched = kcl_tdes_keysched; cipher->process = kcl_tdes_process; cipher->finish = kcl_tdes_finish; kcl_tdes_size(cipher->ctx, &cipher->blockSize, &cipher->keySize); }
void xs_cbc_init(xsMachine *the) { crypt_mode_t *mode = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc); mode->encrypt = cbc_encrypt; mode->decrypt = cbc_decrypt; mode->direction = -1; mode->maxSlop = mode->cipher->blockSize; memset(mode->em_buf, 0, sizeof(mode->em_buf)); if (ac > 0 && xsTest(xsArg(0))) { /* iv */ size_t ivsize = xsGetArrayBufferLength(xsArg(0)); void *iv = xsToArrayBuffer(xsArg(0)); cbc_setIV(mode, iv, ivsize); } mode->padding = ac > 1 && xsToBoolean(xsArg(1)); }
void xs_ctr_init(xsMachine *the) { crypt_mode_t *mode = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc); mode->encrypt = ctr_process; mode->decrypt = ctr_process; mode->setIV = ctr_setIV; mode->maxSlop = 0; c_memset(mode->em_buf, 0, sizeof(mode->em_buf)); if (ac > 0 && xsTest(xsArg(0))) { /* iv */ void *iv = xsToArrayBuffer(xsArg(0)); size_t ivsize = xsGetArrayBufferLength(xsArg(0)); ctr_setIV(mode, iv, ivsize); } (*mode->cipher->keysched)(mode->cipher->ctx, KCL_DIRECTION_ENCRYPTION); /* CTR uses encryption only */ }
void xs_digest_update(xsMachine *the) { crypt_digest_t *digest = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc), i; int len; void *data; for (i = 0; i < ac; i++) { if (xsTypeOf(xsArg(i)) == xsStringType) { data = xsToString(xsArg(i)); len = strlen(data); } else { len = xsGetArrayBufferLength(xsArg(i)); data = xsToArrayBuffer(xsArg(i)); } (*digest->update)(digest->ctx, data, len); } }
void xs_i2c_read(xsMachine *the) { wm_i2c *i2c = xsGetHostData(xsThis); int nbytes = xsToInteger(xsArg(1)); int reg; switch (xsTypeOf(xsArg(0))) { case xsNumberType: case xsIntegerType: reg = xsToInteger(xsArg(0)); break; default: reg = -1; break; } xsResult = xsArrayBuffer(NULL, nbytes); if (mc_i2c_read(i2c, reg, xsToArrayBuffer(xsResult), nbytes) != 0) xsSetUndefined(xsResult); }
void KPR_mqttclient_connect(xsMachine* the) { KPR_MQTTClientRecord *self = xsGetHostData(xsThis); char *host; UInt16 port; KprMQTTClientConnectOptions options; if (xsToInteger(xsArgc) != 10) xsThrowIfFskErr(kFskErrParameterError); host = xsToString(xsArg(0)); port = xsToInteger(xsArg(1)); options.isSecure = xsToBoolean(xsArg(2)); options.keepAlive = xsToInteger(xsArg(3)); options.username = xsTest(xsArg(4)) ? xsToString(xsArg(4)) : NULL; options.password = xsTest(xsArg(5)) ? xsToString(xsArg(5)) : NULL; options.willIsRetained = false; options.willQualityOfService = 0; options.willTopic = NULL; options.willPayload = NULL; options.willPayloadLength = 0; if (xsTest(xsArg(6))) { options.willTopic = xsToString(xsArg(6)); options.willQualityOfService = xsToInteger(xsArg(7)); options.willIsRetained = xsToBoolean(xsArg(8)); if (xsTest(xsArg(9))) { if (isArrayBuffer(xsArg(9))) { options.willPayload = xsToArrayBuffer(xsArg(9)); options.willPayloadLength = xsGetArrayBufferLength(xsArg(9)); } else { options.willPayload = xsToString(xsArg(9)); options.willPayloadLength = FskStrLen(options.willPayload); } } } xsThrowIfFskErr(KprMQTTClientConnect(self->client, host, port, &options)); }
unsigned char *writeOne(xsMachine *the, xsI2C i2c, xsSlot *slot, unsigned char *bufPtr, unsigned char *bufEnd) { xsType argType = xsTypeOf(*slot); switch (argType) { case xsIntegerType: case xsNumberType: { SInt32 value = xsToInteger(*slot); if ((value < 0) || (value > 255)) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write invalid character value %s.", i2c->diagnosticID); if ((bufEnd - bufPtr) < 1) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); *bufPtr++ = (char)value; } break; case xsStringType: { char *text = xsToString(*slot); SInt32 dataSize = FskStrLen(text); if ((bufEnd - bufPtr) < dataSize) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); FskMemMove(bufPtr, text, dataSize); bufPtr += dataSize; } break; case xsReferenceType: if (xsIsInstanceOf(*slot, xsArrayBufferPrototype)) { char *data = xsToArrayBuffer(*slot); SInt32 dataSize = xsGetArrayBufferLength(*slot); if ((bufEnd - bufPtr) < dataSize) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); FskMemMove(bufPtr, data, dataSize); bufPtr += dataSize; } else if (xsIsInstanceOf(*slot, xsChunkPrototype)) { char *data = xsGetHostData(*slot); SInt32 dataSize = xsToInteger(xsGet(*slot, xsID("length"))); if ((bufEnd - bufPtr) < dataSize) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); FskMemMove(bufPtr, data, dataSize); bufPtr += dataSize; } else if (xsIsInstanceOf(*slot, xsArrayPrototype)) { SInt32 length = xsToInteger(xsGet(*slot, xsID("length"))), j; if ((bufEnd - bufPtr) < length) xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C write 32 byte write max %s.", i2c->diagnosticID); for (j = 0; j < length; j++) { xsSlot item = xsGet(*slot, j); bufPtr = writeOne(the, i2c, &item, bufPtr, bufEnd); } } else xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C unsupported argument type passed to write %s.", i2c->diagnosticID); break; default: xsThrowDiagnosticIfFskErr(kFskErrInvalidParameter, "I2C unsupported argument type passed to write %s.", i2c->diagnosticID); break; } return bufPtr; }
void xs_i2c_write(xsMachine *the) { wm_i2c *i2c = xsGetHostData(xsThis); int ac = xsToInteger(xsArgc); int reg; uint8_t *data; int datasize; uint8_t num; uint8_t *allocated = NULL; if (ac < 2) return; #if I2C_SUPPORT_CONCURRENCY if (i2c->slave_addr != i2c_current_slave_addr) i2c_config(i2c); #endif switch (xsTypeOf(xsArg(0))) { case xsNumberType: case xsIntegerType: reg = xsToInteger(xsArg(0)); break; default: reg = -1; break; } switch (xsTypeOf(xsArg(1))) { case xsIntegerType: case xsNumberType: num = (uint8_t)xsToInteger(xsArg(1)); data = # datasize = 1; break; case xsReferenceType: if (xsIsInstanceOf(xsArg(1), xsArrayPrototype)) { int i; xsVars(1); xsGet(xsVar(0), xsArg(1), xsID("length")); datasize = xsToInteger(xsVar(0)); if ((allocated = mc_malloc(datasize)) == NULL) mc_xs_throw(the, "no mem"); for (i = 0; i < datasize; i++) { xsGet(xsVar(0), xsArg(1), (xsIndex)i); allocated[i] = (uint8_t)xsToInteger(xsVar(0)); } data = allocated; } else { datasize = xsGetArrayBufferLength(xsArg(1)); data = xsToArrayBuffer(xsArg(1)); } break; default: mc_xs_throw(the, "args"); return; /* NOT REACHED */ } if (ac > 2) { int n = xsToInteger(xsArg(2)); if (datasize > n) datasize = n; } if (!i2c_wait_for_ack(i2c, i2c->txtout)) mc_log_debug("I2C: write: no ack!\n"); if (!i2c_write_bytes(i2c, reg, data, datasize)) goto bail; (void)i2c_wait_tx_fifo(i2c); /* send the stop sequence */ if (allocated != NULL) mc_free(allocated); xsSetTrue(xsResult); bail: return; }