+static int nl_add_key(struct nl_msg *msg, wpa_alg alg,
+ int key_idx, int defkey,
+ const u8 *seq, size_t seq_len,
+ const u8 *key, size_t key_len)
+{
+ struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
+ if (!key_attr)
+ return -1;
+
+ if (defkey && alg == WPA_ALG_IGTK)
+ NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
+ else if (defkey)
+ NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
+
+ NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
+
+ switch (alg) {
+ case WPA_ALG_WEP:
+ if (key_len == 5)
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC01);
+ else
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC05);
+ break;
+ case WPA_ALG_TKIP:
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC02);
+ break;
+ case WPA_ALG_CCMP:
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC04);
+ break;
+ case WPA_ALG_IGTK:
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC06);
+ break;
+ default:
+ wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
+ "algorithm %d", __func__, alg);
+ return -1;
+ }
+
+ if (seq && seq_len)
+ NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
+
+ NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
+
+ nla_nest_end(msg, key_attr);
+
+ return 0;
+ nla_put_failure:
+ return -1;
+}
+