|
I'm getting a bus violation after my NIF code is run. The code is pretty straightforward: I'm extending crypto:aes_ctr_encrypt/3 to allow for real streaming encryption. Unfortunately, something is unhappy because after I return from the BIF, I get the bus violation. I figure I'm either missing something stupid-obvious or there are some side-effects I'm not aware of in some of the enif_* functions.
I've included my function (aes_ctr_encrypt_with_state as well as the original aes_ctr_encrypt. State is an arity-4 tuple containing the key (an iolist or binary), the IV (a binary of length 16), ECount (a binary of length 16 initialized to all zeros), and Num (an integer set to 0). There is another function that (correctly) initializes that (it is Erlang code and working fine). (Code also available at http://pastebin.com/fPs7SgiR) Any ideas or thoughts would be much appreciated.
Travis Jensen Read the Software Maven @ http://softwaremaven.innerbrane.com/ Read my LinkedIn profile @ http://www.linkedin.com/in/travisjensen Read my Twitter mumblings @ http://twitter.com/SoftwareMaven Send me email @ [hidden email] *What kind of guy calls himself the Software Maven???* _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
|
# Travis Jensen 2011-04-28:
> [... This results in SIGBUS after returning to Erlang ...] > > 1. static ERL_NIF_TERM aes_ctr_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM > argv[]) > 2. {/* ({Key, IVec, ECount, Num}, Data) */ > 3. ErlNifBinary key_bin, ivec_bin, text_bin, ecount_bin; > 4. AES_KEY aes_key; > 5. unsigned int num = 0; > 6. ERL_NIF_TERM ret, num2_term, cipher_term, ivec2_term, ecount2_term, new_state_term; > 7. int state_arity; > 8. const ERL_NIF_TERM *state_term; > 9. unsigned char * ivec2_buf; > 10. unsigned char * ecount2_buf; > 11. > 12. if (!enif_get_tuple(env, argv[0], &state_arity, &state_term) > 13. || state_arity != 4 > 14. || !enif_inspect_iolist_as_binary(env, state_term[0], &key_bin) > 15. || AES_set_encrypt_key(key_bin.data, key_bin.size*8, &aes_key) != 0 > 16. || !enif_inspect_binary(env, state_term[1], &ivec_bin) || ivec_bin.size != 16 > 17. || !enif_inspect_binary(env, state_term[2], &ecount_bin) || ecount_bin.size != > AES_BLOCK_SIZE > 18. || !enif_get_uint(env, state_term[3], &num) > 19. || !enif_inspect_iolist_as_binary(env, argv[1], &text_bin)) { > 20. return enif_make_badarg(env); > 21. } > 22. > 23. ivec2_buf = enif_make_new_binary(env, ivec_bin.size, &ivec2_term); > 24. ecount2_buf = enif_make_new_binary(env, ecount_bin.size, &ecount2_term); > 25. > 26. memcpy(ivec2_buf, ivec_bin.data, 16); > 27. memcpy(ecount2_buf, ecount_bin.data, ecount_bin.size); > 28. > 29. AES_ctr128_encrypt((unsigned char *) text_bin.data, > 30. enif_make_new_binary(env, text_bin.size, &cipher_term), > 31. text_bin.size, &aes_key, ivec2_buf, ecount2_buf, &num); > 32. > 33. num2_term = enif_make_uint(env, num); > 34. new_state_term = enif_make_tuple4(env, key_bin, ivec2_term, ecount2_term, num2_term); > 35. ret = enif_make_tuple2(env, new_state_term, cipher_term); > 36. return ret; > 37. } Just a random guess really, but your key_bin doesn't seem to be a proper term suitable for returning to Erlang, shoudln't you run enif_make_binary() on it? The compiler should warn you about that too, unless ERL_NIF_TERM is something hopelessly vague like "void *"... Regards, -- Jachym _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
|
Jachym Holecek wrote:
> # Travis Jensen 2011-04-28: > >> [... This results in SIGBUS after returning to Erlang ...] >> >> 1. static ERL_NIF_TERM aes_ctr_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM >> argv[]) >> 2. {/* ({Key, IVec, ECount, Num}, Data) */ >> 3. ErlNifBinary key_bin, ivec_bin, text_bin, ecount_bin; >> >> >> 34. new_state_term = enif_make_tuple4(env, key_bin, ivec2_term, ecount2_term, num2_term); >> 35. ret = enif_make_tuple2(env, new_state_term, cipher_term); >> 36. return ret; >> 37. } >> > > Just a random guess really, but your key_bin doesn't seem to be a proper term > suitable for returning to Erlang, shoudln't you run enif_make_binary() on it? > The compiler should warn you about that too, unless ERL_NIF_TERM is something > hopelessly vague like "void *"... > > Regards, > -- Jachym > > The reason the compiler did not complain is that enif_make_tuple4 is a macro calling variadic function enif_make_tuple(ErlNifEnv*, ...). A patch turning enif_make_tuple# and enif_make_list# into inline functions (if compiler supports it) would probably be a good idea. Any takers? /Sverker, Erlang/OTP _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by Jachym Holecek
On Thu, Apr 28, 2011 at 4:07 AM, Jachym Holecek <[hidden email]> wrote:
That was a really good random guess. :) Replaced that with the term passed in (since it doesn't change) and it worked perfectly. Thanks for your sharp eyes! tj
-- Travis Jensen Read the Software Maven @ http://softwaremaven.innerbrane.com/ Read my LinkedIn profile @ http://www.linkedin.com/in/travisjensen Read my Twitter mumblings @ http://twitter.com/SoftwareMaven Send me email @ [hidden email] *What kind of guy calls himself the Software Maven???* _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
| Powered by Nabble | Edit this page |
